<commit_before>/** @file
 *
 * @ingroup modularSystem
 *
 * @brief System scheduler class
 *
 * @details
 *
 * @authors Théo de la Hogue
 *
 * @copyright © 2013, Théo de la Hogue @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "Scheduler.h"
#include "System.h"

#define thisTTClass                 System
#define thisTTClassName             "System"
#define thisTTClassTags             "scheduler, System"

#define thisSchedulerVersion		"0.1"
#define thisSchedulerAuthor         "Theo de la Hogue"
#define thisSchedulerStretchable	YES

extern "C" TT_EXTENSION_EXPORT TTErr TTLoadJamomaExtension_System(void)
{
	TTFoundationInit();
	System::registerClass();
	return kTTErrNone;
}

SCHEDULER_CONSTRUCTOR,
mGranularity(20.0),
mThread(NULL)
{
	SCHEDULER_INITIALIZE

    addAttribute(Granularity, kTypeUInt32);
}

System::~System()
{
    // if a thread is running
    if (mThread) {

        // stop thread execution
		mThread->wait();
        delete mThread;
        mThread = NULL;
    }
}

TTErr System::getParameterNames(TTValue& value)
{
	value.clear();
	//value.append(TTSymbol("aParameter"));

	return kTTErrNone;
}

TTErr System::Go()
{
    // do we need to ramp at all ?
    if (mDuration <= 0.) {

        mRunning = NO;
        mProgression = 0.;
        mRealTime = 0.;

        (mCallback)(mBaton, mProgression);

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);          // we use kTTSym_notify because we know that observers are TTCallback

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);  // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);  // we use kTTSym_notify because we know that observers are TTCallback
    }
    // if the thread is not running
    else if (mThread == NULL) {

        // launch a new thread to run the scheduler execution
        mThread = new TTThread(TTThreadCallbackType(&SystemThreadCallback), (TTPtr)this);

    }

    return kTTErrNone;
}

TTErr System::Stop()
{
	mRunning = NO;

    // if a thread is running
    if (mThread) {

        // stop thread execution
		mThread->wait();
        delete mThread;
        mThread = NULL;

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);          // we use kTTSym_notify because we know that observers are TTCallback
    }

    return kTTErrNone;
}

TTErr System::Tick()
{
    TTFloat64 delta = computeDeltaTime();

    mProgression += (delta * mSpeed) / mDuration;
    mRealTime += delta;

    if (mProgression < 1.) {

        (mCallback)(mBaton, mProgression);

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);    // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);          // we use kTTSym_notify because we know that observers are TTCallback
    }
    else {

        mRunning = NO;

        (mCallback)(mBaton, mProgression);

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);    // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);          // we use kTTSym_notify because we know that observers are TTCallback

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);            // we use kTTSym_notify because we know that observers are TTCallback
    }

    return kTTErrNone;
}

TTErr System::Pause()
{
    return kTTErrGeneric;
}

TTErr System::Resume()
{
    return kTTErrGeneric;
}

TTFloat64 System::computeDeltaTime()
{
	struct timeval tv;
	struct timezone tz;

	TTUInt64 deltaInUs = 0;
    TTUInt64 granularityInUs = mGranularity * 1000;

    // get the current time (in µs)
    gettimeofday(&tv, &tz);
	TTUInt64 currentTime = tv.tv_sec * 1000000L + tv.tv_usec;

	if (mLastTime != 0) {

		deltaInUs = (currentTime - mLastTime);

		if (deltaInUs < granularityInUs) {

			usleep(granularityInUs - deltaInUs);

			deltaInUs = granularityInUs;
		}

		mLastTime += deltaInUs;
	}
    else
		mLastTime = currentTime;

    // return the delta in ms
	return TTFloat64(deltaInUs / 1000.);
}

void SystemThreadCallback(void* anSystemScheduler)
{
    SystemPtr aScheduler = SystemPtr(anSystemScheduler);

    // reset timing informations
    aScheduler->mRunning = YES;
    aScheduler->mProgression = 0.;
    aScheduler->mRealTime = 0.;
    aScheduler->mLastTime = 0;

    // notify each running attribute observers
    aScheduler->runningAttribute->sendNotification(kTTSym_notify, aScheduler->mRunning);          // we use kTTSym_notify because we know that observers are TTCallback

    // launch the tick if the duration is valid and while it have to run
    if (aScheduler->mDuration > 0.)
        while(aScheduler->mRunning)
            aScheduler->Tick();
}
<commit_msg>Forcing the progression to 1.<commit_after>/** @file
 *
 * @ingroup modularSystem
 *
 * @brief System scheduler class
 *
 * @details
 *
 * @authors Théo de la Hogue
 *
 * @copyright © 2013, Théo de la Hogue @n
 * This code is licensed under the terms of the "New BSD License" @n
 * http://creativecommons.org/licenses/BSD/
 */

#include "Scheduler.h"
#include "System.h"

#define thisTTClass                 System
#define thisTTClassName             "System"
#define thisTTClassTags             "scheduler, System"

#define thisSchedulerVersion		"0.1"
#define thisSchedulerAuthor         "Theo de la Hogue"
#define thisSchedulerStretchable	YES

extern "C" TT_EXTENSION_EXPORT TTErr TTLoadJamomaExtension_System(void)
{
	TTFoundationInit();
	System::registerClass();
	return kTTErrNone;
}

SCHEDULER_CONSTRUCTOR,
mGranularity(20.0),
mThread(NULL)
{
	SCHEDULER_INITIALIZE

    addAttribute(Granularity, kTypeUInt32);
}

System::~System()
{
    // if a thread is running
    if (mThread) {

        // stop thread execution
		mThread->wait();
        delete mThread;
        mThread = NULL;
    }
}

TTErr System::getParameterNames(TTValue& value)
{
	value.clear();
	//value.append(TTSymbol("aParameter"));

	return kTTErrNone;
}

TTErr System::Go()
{
    // do we need to ramp at all ?
    if (mDuration <= 0.) {

        mRunning = NO;
        mProgression = 0.;
        mRealTime = 0.;

        (mCallback)(mBaton, mProgression);

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);          // we use kTTSym_notify because we know that observers are TTCallback

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);  // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);  // we use kTTSym_notify because we know that observers are TTCallback
    }
    // if the thread is not running
    else if (mThread == NULL) {

        // launch a new thread to run the scheduler execution
        mThread = new TTThread(TTThreadCallbackType(&SystemThreadCallback), (TTPtr)this);

    }

    return kTTErrNone;
}

TTErr System::Stop()
{
	mRunning = NO;

    // if a thread is running
    if (mThread) {

        // stop thread execution
		mThread->wait();
        delete mThread;
        mThread = NULL;

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);          // we use kTTSym_notify because we know that observers are TTCallback
    }

    return kTTErrNone;
}

TTErr System::Tick()
{
    TTFloat64 delta = computeDeltaTime();

    mProgression += (delta * mSpeed) / mDuration;
    mRealTime += delta;

    if (mProgression < 1.) {

        (mCallback)(mBaton, mProgression);

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);    // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);          // we use kTTSym_notify because we know that observers are TTCallback
    }
    else {

        mRunning = NO;

        // forcing progression to 1. to allow filtering
        mProgression = 1.;

        (mCallback)(mBaton, mProgression);

        // notify each progression attribute observers
        progressionAttribute->sendNotification(kTTSym_notify, mProgression);    // we use kTTSym_notify because we know that observers are TTCallback

        // notify each elapsed time attribute observers
        realTimeAttribute->sendNotification(kTTSym_notify, mRealTime);          // we use kTTSym_notify because we know that observers are TTCallback

        // notify each running attribute observers
        runningAttribute->sendNotification(kTTSym_notify, mRunning);            // we use kTTSym_notify because we know that observers are TTCallback
    }

    return kTTErrNone;
}

TTErr System::Pause()
{
    return kTTErrGeneric;
}

TTErr System::Resume()
{
    return kTTErrGeneric;
}

TTFloat64 System::computeDeltaTime()
{
	struct timeval tv;
	struct timezone tz;

	TTUInt64 deltaInUs = 0;
    TTUInt64 granularityInUs = mGranularity * 1000;

    // get the current time (in µs)
    gettimeofday(&tv, &tz);
	TTUInt64 currentTime = tv.tv_sec * 1000000L + tv.tv_usec;

	if (mLastTime != 0) {

		deltaInUs = (currentTime - mLastTime);

		if (deltaInUs < granularityInUs) {

			usleep(granularityInUs - deltaInUs);

			deltaInUs = granularityInUs;
		}

		mLastTime += deltaInUs;
	}
    else
		mLastTime = currentTime;

    // return the delta in ms
	return TTFloat64(deltaInUs / 1000.);
}

void SystemThreadCallback(void* anSystemScheduler)
{
    SystemPtr aScheduler = SystemPtr(anSystemScheduler);

    // reset timing informations
    aScheduler->mRunning = YES;
    aScheduler->mProgression = 0.;
    aScheduler->mRealTime = 0.;
    aScheduler->mLastTime = 0;

    // notify each running attribute observers
    aScheduler->runningAttribute->sendNotification(kTTSym_notify, aScheduler->mRunning);          // we use kTTSym_notify because we know that observers are TTCallback

    // launch the tick if the duration is valid and while it have to run
    if (aScheduler->mDuration > 0.)
        while(aScheduler->mRunning)
            aScheduler->Tick();
}
<|endoftext|>


<commit_before>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

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

*/

#include "objectdescriptionmodel.h"
#include "objectdescriptionmodel_p.h"
#include <QList>
#include "objectdescription.h"

#ifdef Q_D
#undef Q_D
#endif
#define Q_D(Class) Class##Private<type> * const d = d_func()

namespace Phonon
{

template<ObjectDescriptionType type>
ObjectDescriptionModel<type>::ObjectDescriptionModel( QObject* parent )
	: QAbstractListModel( parent )
	, d_ptr( new ObjectDescriptionModelPrivate<type> )
{
	d_ptr->q_ptr = this;
}

template<ObjectDescriptionType type>
ObjectDescriptionModel<type>::~ObjectDescriptionModel()
{
	delete d_ptr;
	d_ptr = 0;
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::setModelData( const QList<ObjectDescription<type> >& newData )
{
	Q_D( ObjectDescriptionModel );
	d->data = newData;
	reset();
}

template<ObjectDescriptionType type>
int ObjectDescriptionModel<type>::rowCount( const QModelIndex& parent ) const
{
	if( parent.isValid() )
		return 0;

	Q_D( const ObjectDescriptionModel );
	return d->data.size();
}

template<ObjectDescriptionType type>
QVariant ObjectDescriptionModel<type>::data( const QModelIndex& index, int role ) const
{
	Q_D( const ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() || index.column() != 0 )
		return QVariant();

	switch( role )
	{
		case Qt::EditRole:
		case Qt::DisplayRole:
			return d->data.at( index.row() ).name();
			break;
		case Qt::ToolTipRole:
			return d->data.at( index.row() ).description();
			break;
		default:
			return QVariant();
	}
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::moveUp( const QModelIndex& index )
{
	Q_D( ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() || index.row() < 1 || index.column() != 0 )
		return;

	QModelIndex above = index.sibling( index.row() - 1, index.column() );
	d->data.swap( index.row(), above.row() );
	QModelIndexList from, to;
	from << index << above;
	to << above << index;
	changePersistentIndexList( from, to );
	emit dataChanged( above, index );
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::moveDown( const QModelIndex& index )
{
	Q_D( ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() - 1 || index.column() != 0 )
		return;

	QModelIndex below = index.sibling( index.row() + 1, index.column() );
	d->data.swap( index.row(), below.row() );
	QModelIndexList from, to;
	from << index << below;
	to << below << index;
	changePersistentIndexList( from, to );
	emit dataChanged( index, below );
}

template<ObjectDescriptionType type>
QList<int> ObjectDescriptionModel<type>::tupleIndexOrder() const
{
	Q_D( const ObjectDescriptionModel );
	QList<int> ret;
	for( int i = 0; i < d->data.size(); ++i )
		ret.append( d->data.at( i ).index() );
	return ret;
}

template<ObjectDescriptionType type>
int ObjectDescriptionModel<type>::tupleIndexAtPositionIndex( int positionIndex ) const
{
	return d_func()->data.at( positionIndex ).index();
}

#define PHONON_INSTANCIATE_ALL_FUNCTIONS( T ) \
	template int ObjectDescriptionModel<T>::tupleIndexAtPositionIndex(int) const; \
    template QList<int> ObjectDescriptionModel<T>::tupleIndexOrder() const; \
    template void ObjectDescriptionModel<T>::moveDown( const QModelIndex& ); \
    template void ObjectDescriptionModel<T>::moveUp( const QModelIndex& ); \
    template QVariant ObjectDescriptionModel<T>::data( const QModelIndex&, int) const; \
    template int ObjectDescriptionModel<T>::rowCount( const QModelIndex& parent ) const; \
    template void ObjectDescriptionModel<T>::setModelData( const QList<ObjectDescription<T> >& ); \
    template ObjectDescriptionModel<T>::~ObjectDescriptionModel(); \
    template ObjectDescriptionModel<T>::ObjectDescriptionModel( QObject* );

PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioOutputDeviceType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioCaptureDeviceType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoOutputDeviceType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoCaptureDeviceType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioEffectType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoEffectType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioCodecType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoCodecType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( ContainerFormatType );
PHONON_INSTANCIATE_ALL_FUNCTIONS( VisualizationType );

#undef PHONON_INSTANCIATE_ALL_FUNCTIONS

}

// vim: sw=4 ts=4 noet
<commit_msg>OK, I take these<commit_after>/*  This file is part of the KDE project
    Copyright (C) 2006 Matthias Kretz <kretz@kde.org>

    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License version 2 as published by the Free Software Foundation.

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

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

*/

#include "objectdescriptionmodel.h"
#include "objectdescriptionmodel_p.h"
#include <QList>
#include "objectdescription.h"

#ifdef Q_D
#undef Q_D
#endif
#define Q_D(Class) Class##Private<type> * const d = d_func()

namespace Phonon
{

template<ObjectDescriptionType type>
ObjectDescriptionModel<type>::ObjectDescriptionModel( QObject* parent )
	: QAbstractListModel( parent )
	, d_ptr( new ObjectDescriptionModelPrivate<type> )
{
	d_ptr->q_ptr = this;
}

template<ObjectDescriptionType type>
ObjectDescriptionModel<type>::~ObjectDescriptionModel()
{
	delete d_ptr;
	d_ptr = 0;
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::setModelData( const QList<ObjectDescription<type> >& newData )
{
	Q_D( ObjectDescriptionModel );
	d->data = newData;
	reset();
}

template<ObjectDescriptionType type>
int ObjectDescriptionModel<type>::rowCount( const QModelIndex& parent ) const
{
	if( parent.isValid() )
		return 0;

	Q_D( const ObjectDescriptionModel );
	return d->data.size();
}

template<ObjectDescriptionType type>
QVariant ObjectDescriptionModel<type>::data( const QModelIndex& index, int role ) const
{
	Q_D( const ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() || index.column() != 0 )
		return QVariant();

	switch( role )
	{
		case Qt::EditRole:
		case Qt::DisplayRole:
			return d->data.at( index.row() ).name();
			break;
		case Qt::ToolTipRole:
			return d->data.at( index.row() ).description();
			break;
		default:
			return QVariant();
	}
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::moveUp( const QModelIndex& index )
{
	Q_D( ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() || index.row() < 1 || index.column() != 0 )
		return;

	QModelIndex above = index.sibling( index.row() - 1, index.column() );
	d->data.swap( index.row(), above.row() );
	QModelIndexList from, to;
	from << index << above;
	to << above << index;
	changePersistentIndexList( from, to );
	emit dataChanged( above, index );
}

template<ObjectDescriptionType type>
void ObjectDescriptionModel<type>::moveDown( const QModelIndex& index )
{
	Q_D( ObjectDescriptionModel );
	if( !index.isValid() || index.row() >= d->data.size() - 1 || index.column() != 0 )
		return;

	QModelIndex below = index.sibling( index.row() + 1, index.column() );
	d->data.swap( index.row(), below.row() );
	QModelIndexList from, to;
	from << index << below;
	to << below << index;
	changePersistentIndexList( from, to );
	emit dataChanged( index, below );
}

template<ObjectDescriptionType type>
QList<int> ObjectDescriptionModel<type>::tupleIndexOrder() const
{
	Q_D( const ObjectDescriptionModel );
	QList<int> ret;
	for( int i = 0; i < d->data.size(); ++i )
		ret.append( d->data.at( i ).index() );
	return ret;
}

template<ObjectDescriptionType type>
int ObjectDescriptionModel<type>::tupleIndexAtPositionIndex( int positionIndex ) const
{
	return d_func()->data.at( positionIndex ).index();
}

#define PHONON_INSTANCIATE_ALL_FUNCTIONS( T ) \
	template int ObjectDescriptionModel<T>::tupleIndexAtPositionIndex(int) const; \
    template QList<int> ObjectDescriptionModel<T>::tupleIndexOrder() const; \
    template void ObjectDescriptionModel<T>::moveDown( const QModelIndex& ); \
    template void ObjectDescriptionModel<T>::moveUp( const QModelIndex& ); \
    template QVariant ObjectDescriptionModel<T>::data( const QModelIndex&, int) const; \
    template int ObjectDescriptionModel<T>::rowCount( const QModelIndex& parent ) const; \
    template void ObjectDescriptionModel<T>::setModelData( const QList<ObjectDescription<T> >& ); \
    template ObjectDescriptionModel<T>::~ObjectDescriptionModel(); \
    template ObjectDescriptionModel<T>::ObjectDescriptionModel( QObject* );

PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioOutputDeviceType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioCaptureDeviceType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoOutputDeviceType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoCaptureDeviceType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioEffectType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoEffectType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( AudioCodecType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( VideoCodecType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( ContainerFormatType )
PHONON_INSTANCIATE_ALL_FUNCTIONS( VisualizationType )

#undef PHONON_INSTANCIATE_ALL_FUNCTIONS

}

// vim: sw=4 ts=4 noet
<|endoftext|>


<commit_before>/**
 * This file is part of the CernVM File System.
 */

#ifndef CVMFS_SSL_H_
#define CVMFS_SSL_H_

#include "ssl.h"

#include <cstdlib>
#include <string>
#include <vector>

#include "duplex_curl.h"
#include "platform.h"
#include "util/posix.h"
#include "util/string.h"

namespace {

bool HasCertificates(std::string directory) {
  if (!DirectoryExists(directory)) return false;

  DIR *dirp = opendir(directory.c_str());
  if (!dirp) return false;

  platform_dirent64 *dirent;
  while ((dirent = platform_readdir(dirp))) {
    platform_stat64 stat;

    if (platform_stat(dirent->d_name, &stat) != 0) continue;
    if (!S_ISREG(stat.st_mode)) continue;

    const std::string filename(dirent->d_name);
    if (HasSuffix(filename, ".pem", /* ignore case = */ true) ||
        HasSuffix(filename, ".crt", /* ignore case = */ true)) {
      closedir(dirp);
      return true;
    }
  }

  closedir(dirp);
  return false;
}

bool Add_CVMFS_SSL_Certificates(CURL *handle) {
  const char *cadir = getenv("X509_CERT_DIR");
  if (!cadir || !*cadir) {
    cadir = "/etc/grid-security/certificates";
  }
  bool certificate_already_added = false;
  if (HasCertificates(cadir)) {
      CURLcode res = curl_easy_setopt(handle, CURLOPT_CAPATH, cadir);
      if (CURLE_OK == res) {
        certificate_already_added = true;
      }
  }
  const char *cabundle = getenv("X509_CERT_BUNDLE");
  if (cabundle && *cabundle) {
    CURLcode res = curl_easy_setopt(handle, CURLOPT_CAINFO, cabundle);
    if (CURLE_OK == res) {
      certificate_already_added = true;
    }
  }

  return certificate_already_added;
}

bool AddSystemSSLCertificates(CURL *handle) {
  std::vector<std::string> cadirs;

  // most systems store the certificates here
  cadirs.push_back("/etc/ssl/certs/");

  cadirs.push_back("/etc/pki/tls/certs/");
  cadirs.push_back("/etc/ssl/");
  cadirs.push_back("/etc/pki/tls/");
  cadirs.push_back("/etc/pki/ca-trust/extracted/pem/");
  cadirs.push_back("/etc/ssl/");

  for (std::vector<std::string>::const_iterator cadir = cadirs.begin();
       cadir != cadirs.end(); ++cadir) {
    if (HasCertificates(*cadir)) {
      CURLcode res = curl_easy_setopt(handle, CURLOPT_CAPATH, (*cadir).c_str());
      if (CURLE_OK == res) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace

bool AddSSLCertificates(CURL *handle, bool add_system_certificates) {
  bool already_added = Add_CVMFS_SSL_Certificates(handle);

  if ((already_added == false) && (add_system_certificates == true)) {
    return AddSystemSSLCertificates(handle);
  }
  return already_added;
}

#endif  // CVMFS_SSL_H_
<commit_msg>fix implementation to check if a directory contains certificates<commit_after>/**
 * This file is part of the CernVM File System.
 */

#ifndef CVMFS_SSL_H_
#define CVMFS_SSL_H_

#include "ssl.h"

#include <cstdlib>
#include <string>
#include <vector>

#include "duplex_curl.h"
#include "platform.h"
#include "util/posix.h"
#include "util/string.h"

namespace {

bool HasCertificates(std::string directory) {
  if (!DirectoryExists(directory)) return false;

  DIR *dirp = opendir(directory.c_str());
  if (!dirp) return false;

  platform_dirent64 *dirent;
  while ((dirent = platform_readdir(dirp))) {
    const std::string filename(directory + std::string(dirent->d_name));

    platform_stat64 stat;
    if (platform_stat(filename.c_str(), &stat) != 0) continue;
    if (!(S_ISREG(stat.st_mode) || S_ISLNK(stat.st_mode))) continue;

    if (HasSuffix(filename, ".pem", /* ignore case = */ true) ||
        HasSuffix(filename, ".crt", /* ignore case = */ true)) {
      closedir(dirp);
      return true;
    }
  }

  closedir(dirp);
  return false;
}

bool Add_CVMFS_SSL_Certificates(CURL *handle) {
  const char *cadir = getenv("X509_CERT_DIR");
  if (!cadir || !*cadir) {
    cadir = "/etc/grid-security/certificates";
  }
  bool certificate_already_added = false;
  if (HasCertificates(cadir)) {
      CURLcode res = curl_easy_setopt(handle, CURLOPT_CAPATH, cadir);
      if (CURLE_OK == res) {
        certificate_already_added = true;
      }
  }
  const char *cabundle = getenv("X509_CERT_BUNDLE");
  if (cabundle && *cabundle) {
    CURLcode res = curl_easy_setopt(handle, CURLOPT_CAINFO, cabundle);
    if (CURLE_OK == res) {
      certificate_already_added = true;
    }
  }

  return certificate_already_added;
}

bool AddSystemSSLCertificates(CURL *handle) {
  std::vector<std::string> cadirs;

  // most systems store the certificates here
  cadirs.push_back("/etc/ssl/certs/");

  cadirs.push_back("/etc/pki/tls/certs/");
  cadirs.push_back("/etc/ssl/");
  cadirs.push_back("/etc/pki/tls/");
  cadirs.push_back("/etc/pki/ca-trust/extracted/pem/");
  cadirs.push_back("/etc/ssl/");

  for (std::vector<std::string>::const_iterator cadir = cadirs.begin();
       cadir != cadirs.end(); ++cadir) {
    if (HasCertificates(*cadir)) {
      CURLcode res = curl_easy_setopt(handle, CURLOPT_CAPATH, (*cadir).c_str());
      if (CURLE_OK == res) {
        return true;
      }
    }
  }

  return false;
}

}  // namespace

bool AddSSLCertificates(CURL *handle, bool add_system_certificates) {
  bool already_added = Add_CVMFS_SSL_Certificates(handle);

  if ((already_added == false) && (add_system_certificates == true)) {
    return AddSystemSSLCertificates(handle);
  }
  return already_added;
}

#endif  // CVMFS_SSL_H_
<|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#undef SC_DLLIMPLEMENTATION

#include "scuiimoptdlg.hxx"
#include "tabvwsh.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include <comphelper/string.hxx>
#include <osl/thread.h>
#include <rtl/tencinfo.h>

//========================================================================
// ScDelimiterTable
//========================================================================

class ScDelimiterTable
{
public:
        ScDelimiterTable( const OUString& rDelTab )
            :   theDelTab ( rDelTab ),
                cSep      ( '\t' ),
                nCount    ( comphelper::string::getTokenCount(rDelTab, '\t') ),
                nIter     ( 0 )
            {}

    sal_uInt16  GetCode( const OUString& rDelimiter ) const;
    OUString  GetDelimiter( sal_Unicode nCode ) const;

    OUString  FirstDel()  { nIter = 0; return theDelTab.getToken( nIter, cSep ); }
    OUString  NextDel()   { nIter +=2; return theDelTab.getToken( nIter, cSep ); }

private:
    const OUString      theDelTab;
    const sal_Unicode   cSep;
    const sal_Int32    nCount;
    sal_Int32          nIter;
};

//------------------------------------------------------------------------

sal_uInt16 ScDelimiterTable::GetCode( const OUString& rDel ) const
{
    sal_Unicode nCode = 0;

    if ( nCount >= 2 )
    {
        sal_Int32 i = 0;
        while ( i<nCount )
        {
            if ( rDel == theDelTab.getToken( i, cSep ) )
            {
                nCode = (sal_Unicode) theDelTab.getToken( i+1, cSep ).toInt32();
                i     = nCount;
            }
            else
                i += 2;
        }
    }

    return nCode;
}

//------------------------------------------------------------------------

OUString ScDelimiterTable::GetDelimiter( sal_Unicode nCode ) const
{
    OUString aStrDel;

    if ( nCount >= 2 )
    {
        sal_Int32 i = 0;
        while ( i<nCount )
        {
            if ( nCode == (sal_Unicode) theDelTab.getToken( i+1, cSep ).toInt32() )
            {
                aStrDel = theDelTab.getToken( i, cSep );
                i       = nCount;
            }
            else
                i += 2;
        }
    }

    return aStrDel;
}

//========================================================================
// ScImportOptionsDlg
//========================================================================

ScImportOptionsDlg::ScImportOptionsDlg(
        Window*                 pParent,
        sal_Bool                    bAscii,
        const ScImportOptions*  pOptions,
        const OUString*         pStrTitle,
        sal_Bool                    bMultiByte,
        sal_Bool                    bOnlyDbtoolsEncodings,
        sal_Bool                    bImport )
    :   ModalDialog ( pParent, "ImOptDialog",
            "modules/scalc/ui/imoptdialog.ui" )
{
    get(m_pFieldFrame, "fieldframe");
    get(m_pFtCharset, "charsetft");
    if (bAscii)
        get(m_pLbCharset, "charsetdropdown");
    else
    {
        get(m_pLbCharset, "charsetlist");
        m_pLbCharset->set_height_request(6 * m_pLbCharset->GetTextHeight());
    }
    m_pLbCharset->Show();
    get(m_pFtFieldSep, "fieldft");
    get(m_pEdFieldSep, "field");
    get(m_pFtTextSep, "textft");
    get(m_pEdTextSep, "text");
    get(m_pCbShown, "asshown");
    get(m_pCbFormulas, "formulas");
    get(m_pCbQuoteAll, "quoteall");
    get(m_pCbFixed, "fixedwidth");
    get(m_pBtnOk, "ok");

    OUString sFieldSep(SC_RESSTR(SCSTR_FIELDSEP));
    sFieldSep = sFieldSep.replaceFirst( "%TAB",   SC_RESSTR(SCSTR_FIELDSEP_TAB) );
    sFieldSep = sFieldSep.replaceFirst( "%SPACE", SC_RESSTR(SCSTR_FIELDSEP_SPACE) );

    // im Ctor-Initializer nicht moeglich (MSC kann das nicht):
    pFieldSepTab = new ScDelimiterTable( sFieldSep );
    pTextSepTab  = new ScDelimiterTable( OUString(ScResId(SCSTR_TEXTSEP)) );

    OUString aStr = pFieldSepTab->FirstDel();
    sal_Unicode nCode;

    while ( !aStr.isEmpty() )
    {
        m_pEdFieldSep->InsertEntry( aStr );
        aStr = pFieldSepTab->NextDel();
    }

    aStr = pTextSepTab->FirstDel();

    while ( !aStr.isEmpty() )
    {
        m_pEdTextSep->InsertEntry( aStr );
        aStr = pTextSepTab->NextDel();
    }

    m_pEdFieldSep->SetText( m_pEdFieldSep->GetEntry(0) );
    m_pEdTextSep->SetText( m_pEdTextSep->GetEntry(0) );

    if ( bOnlyDbtoolsEncodings )
    {
        // Even dBase export allows multibyte now
        if ( bMultiByte )
            m_pLbCharset->FillFromDbTextEncodingMap( bImport );
        else
            m_pLbCharset->FillFromDbTextEncodingMap( bImport, RTL_TEXTENCODING_INFO_MULTIBYTE );
    }
    else if ( !bAscii )
    {   //!TODO: Unicode would need work in each filter
        if ( bMultiByte )
            m_pLbCharset->FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE );
        else
            m_pLbCharset->FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE |
                RTL_TEXTENCODING_INFO_MULTIBYTE );
    }
    else
    {
        if ( pOptions )
        {
            nCode = pOptions->nFieldSepCode;
            aStr  = pFieldSepTab->GetDelimiter( nCode );

            if ( aStr.isEmpty() )
                m_pEdFieldSep->SetText( OUString((sal_Unicode)nCode) );
            else
                m_pEdFieldSep->SetText( aStr );

            nCode = pOptions->nTextSepCode;
            aStr  = pTextSepTab->GetDelimiter( nCode );

            if ( aStr.isEmpty() )
                m_pEdTextSep->SetText( OUString((sal_Unicode)nCode) );
            else
                m_pEdTextSep->SetText( aStr );
        }
        // all encodings allowed, even Unicode
        m_pLbCharset->FillFromTextEncodingTable( bImport );
    }

    if( bAscii )
    {
        m_pCbFixed->Show();
        m_pCbFixed->SetClickHdl( LINK( this, ScImportOptionsDlg, FixedWidthHdl ) );
        m_pCbFixed->Check( false );
        m_pCbShown->Show();
        m_pCbShown->Check( sal_True );
        m_pCbQuoteAll->Show();
        m_pCbQuoteAll->Check( false );
        m_pCbFormulas->Show();
        ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current());
        bool bFormulas = (pViewSh ?
                pViewSh->GetViewData()->GetOptions().GetOption( VOPT_FORMULAS) :
                false);
        m_pCbFormulas->Check( bFormulas );
    }
    else
    {
        m_pFieldFrame->set_label(m_pFtCharset->GetText());
        m_pFtFieldSep->Hide();
        m_pFtTextSep->Hide();
        m_pFtCharset->Hide();
        m_pEdFieldSep->Hide();
        m_pEdTextSep->Hide();
        m_pCbFixed->Hide();
        m_pCbShown->Hide();
        m_pCbQuoteAll->Hide();
        m_pCbFormulas->Hide();
        m_pLbCharset->GrabFocus();
        m_pLbCharset->SetDoubleClickHdl( LINK( this, ScImportOptionsDlg, DoubleClickHdl ) );
    }

    m_pLbCharset->SelectTextEncoding( pOptions ? pOptions->eCharSet :
        osl_getThreadTextEncoding() );

    // optionaler Titel:
    if ( pStrTitle )
        SetText( *pStrTitle );
}

//------------------------------------------------------------------------

ScImportOptionsDlg::~ScImportOptionsDlg()
{
    delete pFieldSepTab;
    delete pTextSepTab;
}

//------------------------------------------------------------------------

void ScImportOptionsDlg::GetImportOptions( ScImportOptions& rOptions ) const
{
    rOptions.SetTextEncoding( m_pLbCharset->GetSelectTextEncoding() );

    if ( m_pCbFixed->IsVisible() )
    {
        rOptions.nFieldSepCode = GetCodeFromCombo( *m_pEdFieldSep );
        rOptions.nTextSepCode  = GetCodeFromCombo( *m_pEdTextSep );
        rOptions.bFixedWidth = m_pCbFixed->IsChecked();
        rOptions.bSaveAsShown = m_pCbShown->IsChecked();
        rOptions.bQuoteAllText = m_pCbQuoteAll->IsChecked();
        rOptions.bSaveFormulas = m_pCbFormulas->IsChecked();
    }
}

//------------------------------------------------------------------------

sal_uInt16 ScImportOptionsDlg::GetCodeFromCombo( const ComboBox& rEd ) const
{
    ScDelimiterTable* pTab;
    OUString  aStr( rEd.GetText() );
    sal_uInt16  nCode;

    if ( &rEd == m_pEdTextSep )
        pTab = pTextSepTab;
    else
        pTab = pFieldSepTab;

    if ( aStr.isEmpty() )
    {
        nCode = 0;          // kein Trennzeichen
    }
    else
    {
        nCode = pTab->GetCode( aStr );

        if ( nCode == 0 )
            nCode = (sal_uInt16)aStr[0];
    }

    return nCode;
}

//------------------------------------------------------------------------

IMPL_LINK( ScImportOptionsDlg, FixedWidthHdl, CheckBox*, pCheckBox )
{
    if (pCheckBox == m_pCbFixed)
    {
        sal_Bool bEnable = !m_pCbFixed->IsChecked();
        m_pFtFieldSep->Enable( bEnable );
        m_pEdFieldSep->Enable( bEnable );
        m_pFtTextSep->Enable( bEnable );
        m_pEdTextSep->Enable( bEnable );
        m_pCbShown->Enable( bEnable );
        m_pCbQuoteAll->Enable( bEnable );
    }
    return 0;
}

IMPL_LINK( ScImportOptionsDlg, DoubleClickHdl, ListBox*, pLb )
{
    if (pLb == m_pLbCharset)
    {
        m_pBtnOk->Click();
    }
    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>sort charsets<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */

#undef SC_DLLIMPLEMENTATION

#include "scuiimoptdlg.hxx"
#include "tabvwsh.hxx"
#include "scresid.hxx"
#include "sc.hrc"
#include <comphelper/string.hxx>
#include <osl/thread.h>
#include <rtl/tencinfo.h>

//========================================================================
// ScDelimiterTable
//========================================================================

class ScDelimiterTable
{
public:
        ScDelimiterTable( const OUString& rDelTab )
            :   theDelTab ( rDelTab ),
                cSep      ( '\t' ),
                nCount    ( comphelper::string::getTokenCount(rDelTab, '\t') ),
                nIter     ( 0 )
            {}

    sal_uInt16  GetCode( const OUString& rDelimiter ) const;
    OUString  GetDelimiter( sal_Unicode nCode ) const;

    OUString  FirstDel()  { nIter = 0; return theDelTab.getToken( nIter, cSep ); }
    OUString  NextDel()   { nIter +=2; return theDelTab.getToken( nIter, cSep ); }

private:
    const OUString      theDelTab;
    const sal_Unicode   cSep;
    const sal_Int32    nCount;
    sal_Int32          nIter;
};

//------------------------------------------------------------------------

sal_uInt16 ScDelimiterTable::GetCode( const OUString& rDel ) const
{
    sal_Unicode nCode = 0;

    if ( nCount >= 2 )
    {
        sal_Int32 i = 0;
        while ( i<nCount )
        {
            if ( rDel == theDelTab.getToken( i, cSep ) )
            {
                nCode = (sal_Unicode) theDelTab.getToken( i+1, cSep ).toInt32();
                i     = nCount;
            }
            else
                i += 2;
        }
    }

    return nCode;
}

//------------------------------------------------------------------------

OUString ScDelimiterTable::GetDelimiter( sal_Unicode nCode ) const
{
    OUString aStrDel;

    if ( nCount >= 2 )
    {
        sal_Int32 i = 0;
        while ( i<nCount )
        {
            if ( nCode == (sal_Unicode) theDelTab.getToken( i+1, cSep ).toInt32() )
            {
                aStrDel = theDelTab.getToken( i, cSep );
                i       = nCount;
            }
            else
                i += 2;
        }
    }

    return aStrDel;
}

//========================================================================
// ScImportOptionsDlg
//========================================================================

ScImportOptionsDlg::ScImportOptionsDlg(
        Window*                 pParent,
        sal_Bool                    bAscii,
        const ScImportOptions*  pOptions,
        const OUString*         pStrTitle,
        sal_Bool                    bMultiByte,
        sal_Bool                    bOnlyDbtoolsEncodings,
        sal_Bool                    bImport )
    :   ModalDialog ( pParent, "ImOptDialog",
            "modules/scalc/ui/imoptdialog.ui" )
{
    get(m_pFieldFrame, "fieldframe");
    get(m_pFtCharset, "charsetft");
    if (bAscii)
        get(m_pLbCharset, "charsetdropdown");
    else
    {
        get(m_pLbCharset, "charsetlist");
        m_pLbCharset->set_height_request(6 * m_pLbCharset->GetTextHeight());
    }
    m_pLbCharset->SetStyle(m_pLbCharset->GetStyle() | WB_SORT);
    m_pLbCharset->Show();
    get(m_pFtFieldSep, "fieldft");
    get(m_pEdFieldSep, "field");
    get(m_pFtTextSep, "textft");
    get(m_pEdTextSep, "text");
    get(m_pCbShown, "asshown");
    get(m_pCbFormulas, "formulas");
    get(m_pCbQuoteAll, "quoteall");
    get(m_pCbFixed, "fixedwidth");
    get(m_pBtnOk, "ok");

    OUString sFieldSep(SC_RESSTR(SCSTR_FIELDSEP));
    sFieldSep = sFieldSep.replaceFirst( "%TAB",   SC_RESSTR(SCSTR_FIELDSEP_TAB) );
    sFieldSep = sFieldSep.replaceFirst( "%SPACE", SC_RESSTR(SCSTR_FIELDSEP_SPACE) );

    // im Ctor-Initializer nicht moeglich (MSC kann das nicht):
    pFieldSepTab = new ScDelimiterTable( sFieldSep );
    pTextSepTab  = new ScDelimiterTable( OUString(ScResId(SCSTR_TEXTSEP)) );

    OUString aStr = pFieldSepTab->FirstDel();
    sal_Unicode nCode;

    while ( !aStr.isEmpty() )
    {
        m_pEdFieldSep->InsertEntry( aStr );
        aStr = pFieldSepTab->NextDel();
    }

    aStr = pTextSepTab->FirstDel();

    while ( !aStr.isEmpty() )
    {
        m_pEdTextSep->InsertEntry( aStr );
        aStr = pTextSepTab->NextDel();
    }

    m_pEdFieldSep->SetText( m_pEdFieldSep->GetEntry(0) );
    m_pEdTextSep->SetText( m_pEdTextSep->GetEntry(0) );

    if ( bOnlyDbtoolsEncodings )
    {
        // Even dBase export allows multibyte now
        if ( bMultiByte )
            m_pLbCharset->FillFromDbTextEncodingMap( bImport );
        else
            m_pLbCharset->FillFromDbTextEncodingMap( bImport, RTL_TEXTENCODING_INFO_MULTIBYTE );
    }
    else if ( !bAscii )
    {   //!TODO: Unicode would need work in each filter
        if ( bMultiByte )
            m_pLbCharset->FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE );
        else
            m_pLbCharset->FillFromTextEncodingTable( bImport, RTL_TEXTENCODING_INFO_UNICODE |
                RTL_TEXTENCODING_INFO_MULTIBYTE );
    }
    else
    {
        if ( pOptions )
        {
            nCode = pOptions->nFieldSepCode;
            aStr  = pFieldSepTab->GetDelimiter( nCode );

            if ( aStr.isEmpty() )
                m_pEdFieldSep->SetText( OUString((sal_Unicode)nCode) );
            else
                m_pEdFieldSep->SetText( aStr );

            nCode = pOptions->nTextSepCode;
            aStr  = pTextSepTab->GetDelimiter( nCode );

            if ( aStr.isEmpty() )
                m_pEdTextSep->SetText( OUString((sal_Unicode)nCode) );
            else
                m_pEdTextSep->SetText( aStr );
        }
        // all encodings allowed, even Unicode
        m_pLbCharset->FillFromTextEncodingTable( bImport );
    }

    if( bAscii )
    {
        m_pCbFixed->Show();
        m_pCbFixed->SetClickHdl( LINK( this, ScImportOptionsDlg, FixedWidthHdl ) );
        m_pCbFixed->Check( false );
        m_pCbShown->Show();
        m_pCbShown->Check( sal_True );
        m_pCbQuoteAll->Show();
        m_pCbQuoteAll->Check( false );
        m_pCbFormulas->Show();
        ScTabViewShell* pViewSh = PTR_CAST( ScTabViewShell, SfxViewShell::Current());
        bool bFormulas = (pViewSh ?
                pViewSh->GetViewData()->GetOptions().GetOption( VOPT_FORMULAS) :
                false);
        m_pCbFormulas->Check( bFormulas );
    }
    else
    {
        m_pFieldFrame->set_label(m_pFtCharset->GetText());
        m_pFtFieldSep->Hide();
        m_pFtTextSep->Hide();
        m_pFtCharset->Hide();
        m_pEdFieldSep->Hide();
        m_pEdTextSep->Hide();
        m_pCbFixed->Hide();
        m_pCbShown->Hide();
        m_pCbQuoteAll->Hide();
        m_pCbFormulas->Hide();
        m_pLbCharset->GrabFocus();
        m_pLbCharset->SetDoubleClickHdl( LINK( this, ScImportOptionsDlg, DoubleClickHdl ) );
    }

    m_pLbCharset->SelectTextEncoding( pOptions ? pOptions->eCharSet :
        osl_getThreadTextEncoding() );

    // optionaler Titel:
    if ( pStrTitle )
        SetText( *pStrTitle );
}

//------------------------------------------------------------------------

ScImportOptionsDlg::~ScImportOptionsDlg()
{
    delete pFieldSepTab;
    delete pTextSepTab;
}

//------------------------------------------------------------------------

void ScImportOptionsDlg::GetImportOptions( ScImportOptions& rOptions ) const
{
    rOptions.SetTextEncoding( m_pLbCharset->GetSelectTextEncoding() );

    if ( m_pCbFixed->IsVisible() )
    {
        rOptions.nFieldSepCode = GetCodeFromCombo( *m_pEdFieldSep );
        rOptions.nTextSepCode  = GetCodeFromCombo( *m_pEdTextSep );
        rOptions.bFixedWidth = m_pCbFixed->IsChecked();
        rOptions.bSaveAsShown = m_pCbShown->IsChecked();
        rOptions.bQuoteAllText = m_pCbQuoteAll->IsChecked();
        rOptions.bSaveFormulas = m_pCbFormulas->IsChecked();
    }
}

//------------------------------------------------------------------------

sal_uInt16 ScImportOptionsDlg::GetCodeFromCombo( const ComboBox& rEd ) const
{
    ScDelimiterTable* pTab;
    OUString  aStr( rEd.GetText() );
    sal_uInt16  nCode;

    if ( &rEd == m_pEdTextSep )
        pTab = pTextSepTab;
    else
        pTab = pFieldSepTab;

    if ( aStr.isEmpty() )
    {
        nCode = 0;          // kein Trennzeichen
    }
    else
    {
        nCode = pTab->GetCode( aStr );

        if ( nCode == 0 )
            nCode = (sal_uInt16)aStr[0];
    }

    return nCode;
}

//------------------------------------------------------------------------

IMPL_LINK( ScImportOptionsDlg, FixedWidthHdl, CheckBox*, pCheckBox )
{
    if (pCheckBox == m_pCbFixed)
    {
        sal_Bool bEnable = !m_pCbFixed->IsChecked();
        m_pFtFieldSep->Enable( bEnable );
        m_pEdFieldSep->Enable( bEnable );
        m_pFtTextSep->Enable( bEnable );
        m_pEdTextSep->Enable( bEnable );
        m_pCbShown->Enable( bEnable );
        m_pCbQuoteAll->Enable( bEnable );
    }
    return 0;
}

IMPL_LINK( ScImportOptionsDlg, DoubleClickHdl, ListBox*, pLb )
{
    if (pLb == m_pLbCharset)
    {
        m_pBtnOk->Click();
    }
    return 0;
}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


<commit_before>#include "consoleui.h"
#include "servicelayer.h"
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

ConsoleUI::ConsoleUI()
{

}

void ConsoleUI::run()
{
    bool run = true;
    while (run)
    {
       cout << " ================================" << endl;
       cout << " Press 1 to add" << endl;
       cout << " Press 2 to sort" << endl;
       cout << " Press 3 to list" << endl;
       cout << " Press 4 to search"  << endl;
       cout << " Press 5 to exit"     << endl;
       cout << " ================================" << endl;

       int choice = 0;
       cin >> choice;

            switch (choice)
            {
            case 1:
                addData();
                break;
            case 2:
                sortData();
                break;
            case 3:
                showData();
                break;
            case 4:
                searchData();
                break;
            case 5:
                run = false;
                break;
            default:
                cout << "Error! Invalid Input" << endl;
            }

    }

}

void ConsoleUI::addData()
{
    string name;
    char gender;
    int birthYear;
    int deathYear;

    cout << "Enter Name: ";
    cin >> name;
    cout << "Enter gender (M/F): ";
    cin >> gender;
    cout << "Enter birth year: ";
    cin >> birthYear;
    cout << "Enter death year (0 for living person): ";
    cin >> deathYear;

    Persons newPerson(name, gender, birthYear, deathYear);
    serve.add(newPerson);
}

void ConsoleUI::showData()
{
    for(size_t i = 0; i < serve.list().size();i++)
    {
        cout << serve.list()[i] ;
    }

}

void ConsoleUI::searchData()
{
    cout << "How would you like to search the data?" << endl;
    cout << " =====================================" << endl;
    cout << " Press 1 to search by name" << endl;
    cout << " Press 2 to search by birth year" << endl;
    cout << "====================================="  << endl;

    int choice = 0;
    cin >> choice;

    switch(choice)
    {
    case 1:
    {
        string n = " ";
        cout << "Enter name: ";
        cin >> n;
        vector<int> v_n = serve.searchByName(n);
        for (unsigned int i = 0; i < v_n.size(); i++) {
            cout << serve.list()[i];
        }
        if (v_n.size() == 0) {
            cout << "No results found\n";
        }
        break;
    }
    case 2:
    {
        int y = 0;
        cout << "Enter year: ";
        cin >> y;
        vector<int> v_y = serve.searchByYear(y);
        for (unsigned int i = 0; i < v_y.size(); i++) {
            cout << serve.list()[i];
        }
        if (v_y.size() == 0) {
            cout << "No results found\n";
        }
        break;
    }
    default:
    {
        cout << "Error! invalid input" << endl;
    }
}
}

void ConsoleUI::sortData()
{
    cout << "How would you like to sort the list?" << endl;
    cout << " ================================" << endl;
    cout << "Press 1 for Name" << endl;
    cout << "Press 2 for Birth Year" << endl;
    cout << "Press 3 for Death Year " << endl;
    cout << "Press 4 for Gender" << endl;
    cout << " ================================" << endl;

    bool error = false;

    do
    {

    int choice = 0;
    cin >> choice;

    switch (choice)
         {
         case 1:
        serve.sort(choice);
        error = false;
             break;
         case 2:
        serve.sort(choice);
        error = false;
             break;
         case 3:
        serve.sort(choice);
        error = false;
             break;
         case 4:
        serve.sort(choice);
        error = false;
             break;
         default:
             cout << "Error! Invalid input!" << endl;
             error = true;
         }
    }
    while (error == true);
}
<commit_msg>minor changes<commit_after>#include "consoleui.h"
#include "servicelayer.h"
#include <fstream>
#include <string>
#include <iostream>

using namespace std;

ConsoleUI::ConsoleUI()
{

}

void ConsoleUI::run()
{
    bool run = true;
    while (run)
    {
       cout << " ================================" << endl;
       cout << " Press 1 to add" << endl;
       cout << " Press 2 to sort" << endl;
       cout << " Press 3 to list" << endl;
       cout << " Press 4 to search"  << endl;
       cout << " Press 5 to exit"     << endl;
       cout << " ================================" << endl;

       int choice = 0;
       cin >> choice;

            switch (choice)
            {
            case 1:
                addData();
                break;
            case 2:
                sortData();
                break;
            case 3:
                showData();
                break;
            case 4:
                searchData();
                break;
            case 5:
                run = false;
                break;
            default:
                cout << "Error! Invalid Input" << endl;
            }

    }

}

void ConsoleUI::addData()
{
    string name;
    char gender;
    int birthYear;
    int deathYear;

    cout << "Enter Name: ";
    cin >> name;
    cout << "Enter gender (M/F): ";
    cin >> gender;
    cout << "Enter birth year: ";
    cin >> birthYear;
    cout << "Enter death year (0 for living person): ";
    cin >> deathYear;

    Persons newPerson(name, gender, birthYear, deathYear);
    serve.add(newPerson);
}

void ConsoleUI::showData()
{
    for(size_t i = 0; i < serve.list().size();i++)
    {
        cout << serve.list()[i] ;
    }

}

void ConsoleUI::searchData()
{
    cout << "How would you like to search the data?" << endl;
    cout << " =====================================" << endl;
    cout << " Press 1 to search by name" << endl;
    cout << " Press 2 to search by birth year" << endl;
    cout << "====================================="  << endl;

    int choice = 0;
    cin >> choice;

    switch(choice)
    {
    case 1:
    {
        string n = " ";
        cout << "Enter name: ";
        cin >> n;
        vector<int> v_n = serve.searchByName(n);
        for (unsigned int i = 0; i < v_n.size(); i++) {
            cout << serve.list()[i];
        }
        if (v_n.size() == 0) {
            cout << "No results found\n";
        }
        break;
    }
    case 2:
    {
        int y = 0;
        cout << "Enter year: ";
        cin >> y;
        vector<int> v_y = serve.searchByYear(y);
        for (unsigned int i = 0; i < v_y.size(); i++) {
            cout << serve.list()[i];
        }
        if (v_y.size() == 0) {
            cout << "No results found\n";
        }
        break;
    }
    default:
    {
        cout << "Error! invalid input" << endl;
    }
}
}

void ConsoleUI::sortData()
{
    cout << "How would you like to sort the list?" << endl;
    cout << " ================================" << endl;
    cout << "Press 1 for Name" << endl;
    cout << "Press 2 for Birth Year" << endl;
    cout << "Press 3 for Death Year " << endl;
    cout << "Press 4 for Gender" << endl;
    cout << " ================================" << endl;

    bool error = false;

    do
    {

    int choice = 0;
    cin >> choice;

    switch (choice)
         {
         case 1:
        serve.sort(choice);
        error = false;
             break;
         case 2:
        serve.sort(choice);
        error = false;
             break;
         case 3:
        serve.sort(choice);
        error = false;
             break;
         case 4:
        serve.sort(choice);
        error = false;
             break;
         default:
             cout << "Error! Invalid input!" << endl;
             error = true;
         }
    }
    while (error);
}
<|endoftext|>


<commit_before>#include "Alembic.h"
#include "AlembicPoints.h"
#include "AlembicXform.h"
#include "SceneEntry.h"
#include "SimpObj.h"
#include "Utility.h"
#include <IParticleObjectExt.h>
#include <ParticleFlow/IParticleChannelID.h>
#include <ParticleFlow/IParticleChannelShape.h>
#include <ParticleFlow/IParticleContainer.h>
#include <ParticleFlow/IParticleGroup.h>
#include <ParticleFlow/IPFSystem.h>

namespace AbcA = ::Alembic::AbcCoreAbstract::ALEMBIC_VERSION_NS;
namespace AbcB = ::Alembic::Abc::ALEMBIC_VERSION_NS;
using namespace AbcA;
using namespace AbcB;

AlembicPoints::AlembicPoints(const SceneEntry &in_Ref, AlembicWriteJob *in_Job)
    : AlembicObject(in_Ref, in_Job)
{
    std::string pointsName = in_Ref.node->GetName();
    std::string xformName = pointsName + "Xfo";

    Alembic::AbcGeom::OXform xform(GetOParent(), xformName.c_str(), GetCurrentJob()->GetAnimatedTs());
    Alembic::AbcGeom::OPoints points(xform, pointsName.c_str(), GetCurrentJob()->GetAnimatedTs());

    // create the generic properties
    mOVisibility = CreateVisibilityProperty(points, GetCurrentJob()->GetAnimatedTs());

    mXformSchema = xform.getSchema();
    mPointsSchema = points.getSchema();

    // create all properties
    mInstanceNamesProperty = OStringArrayProperty(mPointsSchema, ".instancenames", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );

    // particle attributes
    mScaleProperty = OV3fArrayProperty(mPointsSchema, ".scale", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mOrientationProperty = OQuatfArrayProperty(mPointsSchema, ".orientation", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mAngularVelocityProperty = OQuatfArrayProperty(mPointsSchema, ".angularvelocity", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mAgeProperty = OFloatArrayProperty(mPointsSchema, ".age", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mMassProperty = OFloatArrayProperty(mPointsSchema, ".mass", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeTypeProperty = OUInt16ArrayProperty(mPointsSchema, ".shapetype", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeTimeProperty = OFloatArrayProperty(mPointsSchema, ".shapetime", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeInstanceIDProperty = OUInt16ArrayProperty(mPointsSchema, ".shapeinstanceid", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mColorProperty = OC4fArrayProperty(mPointsSchema, ".color", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
}

AlembicPoints::~AlembicPoints()
{
    // we have to clear this prior to destruction this is a workaround for issue-171
    mOVisibility.reset();
}

Alembic::Abc::OCompoundProperty AlembicPoints::GetCompound()
{
    return mPointsSchema;
}

bool AlembicPoints::Save(double time)
{
    // Note: Particles are always considered to be animated even though
    //       the node does not have the IsAnimated() flag.

    // Extract our particle emitter at the given time
    TimeValue ticks = GetTimeValueFromFrame(time);
    Object *obj = GetRef().node->EvalWorldState(ticks).obj;
    IPFSystem *particleSystem = PFSystemInterface(obj);
    if (particleSystem == NULL)
    {
        return false;
    }

    IParticleObjectExt *particlesExt = GetParticleObjectExtInterface(obj);
    if (particlesExt == NULL)
    {
        return false;
    }

    particlesExt->UpdateParticles(GetRef().node, ticks);
    int numParticles = particlesExt->NumParticles();

    // Set the visibility
    float flVisibility = GetRef().node->GetLocalVisibility(ticks);
    mOVisibility.set(flVisibility > 0 ? Alembic::AbcGeom::kVisibilityVisible : Alembic::AbcGeom::kVisibilityHidden);

    float masterScaleUnitMeters = (float)GetMasterScale(UNITS_METERS);

    // Store positions, velocity, width/size, scale, id, bounding box
    std::vector<Alembic::Abc::V3f> positionVec(numParticles);
    std::vector<Alembic::Abc::V3f> velocityVec(numParticles);
    std::vector<Alembic::Abc::V3f> scaleVec(numParticles);
    std::vector<float> widthVec(numParticles);
    std::vector<float> ageVec(numParticles);
    std::vector<float> massVec;
    std::vector<float> shapeTimeVec;
    std::vector<uint64_t> idVec(numParticles);
    std::vector<uint16_t> shapeTypeVec;
    std::vector<uint16_t> shapeInstanceIDVec;
    std::vector<Alembic::Abc::Quatf> orientationVec(numParticles);
    std::vector<Alembic::Abc::Quatf> angularVelocityVec(numParticles);
    std::vector<Alembic::Abc::C4f> colorVec;
    std::vector<std::string> instanceNamesVec;
    Alembic::Abc::Quatf orientation;
    Alembic::Abc::Quatf spin;
    Alembic::Abc::Box3d bbox;
    bool constantPos = true;
    bool constantVel = true;
    bool constantScale = true;
    bool constantWidth = true;
    bool constantAge = true;
    bool constantOrientation = true;
    bool constantAngularVel = true;

    for (int i = 0; i < numParticles; ++i)
    {
        Imath::V3f pos = ConvertMaxPointToAlembicPoint(*particlesExt->GetParticlePositionByIndex(i), masterScaleUnitMeters);
        Imath::V3f vel = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleSpeedByIndex(i), masterScaleUnitMeters, true);
        Imath::V3f scale = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleScaleXYZByIndex(i), masterScaleUnitMeters, false);
        float width = particlesExt->GetParticleScaleByIndex(i) * GetInchesToDecimetersRatio( masterScaleUnitMeters );
        TimeValue age = particlesExt->GetParticleAgeByIndex(i);
        uint64_t id = particlesExt->GetParticleBornIndex(i);
        ConvertMaxEulerXYZToAlembicQuat(*particlesExt->GetParticleOrientationByIndex(i), &orientation);
        ConvertMaxAngAxisToAlembicQuat(*particlesExt->GetParticleSpinByIndex(i), &spin);

        /*
        Mesh *mesh = particlesExt->GetParticleShapeByIndex(i);
        INode *particleGroupNode = particlesExt->GetParticleGroup(i);
        Object *particleGroupObj = (particleGroupNode != NULL) ? particleGroupNode->EvalWorldState(ticks).obj : NULL;
        IParticleGroup *particleGroup = GetParticleGroupInterface(particleGroupObj);
        ::IObject *particleContainerObject = (particleGroup != NULL) ? particleGroup->GetParticleContainer() : NULL;
        IParticleChannelIDR *chID = GetParticleChannelIDRInterface(particleContainerObject);
        if (chID != NULL)
        {
            id = chID->GetParticleIndex(i);
        }
        IParticleChannelMeshR *channelMesh = GetParticleChannelShapeRInterface(particleContainerObject);
        if (channelMesh != NULL)
        {
            bool isShared = channelMesh->IsShared();
            const Mesh *mesh = channelMesh->GetValue(i);
        }
        */

        positionVec[i].setValue(pos.x, pos.y, pos.z);
        velocityVec[i].setValue(vel.x, vel.y, vel.z);
        scaleVec[i].setValue(scale.x, scale.y, scale.z);
        widthVec[i] = width;
        ageVec[i] = static_cast<float>(GetSecondsFromTimeValue(age));
        idVec[i] = id;
        orientationVec[i] = orientation;
        angularVelocityVec[i] = spin;
        bbox.extendBy(positionVec[i]);

        constantPos &= (positionVec[i] == positionVec[0]);
        constantVel &= (velocityVec[i] == velocityVec[0]);
        constantScale &= (scaleVec[i] == scaleVec[0]);
        constantWidth &= (widthVec[i] == widthVec[0]);
        constantAge &= (ageVec[i] == ageVec[0]);
        constantOrientation &= (orientationVec[i] == orientationVec[0]);
        constantAngularVel &= (angularVelocityVec[i] == angularVelocityVec[0]);
    }

    // Set constant properties that are not currently supported by Max
    massVec.push_back(1.0f);
    shapeTimeVec.push_back(1.0f);
    shapeTypeVec.push_back(ShapeType_Point);
    shapeInstanceIDVec.push_back(0);
    colorVec.push_back(Alembic::Abc::C4f(0.0f, 0.0f, 0.0f, 1.0f));
    instanceNamesVec.push_back("");

    if (numParticles == 0)
    {
        positionVec.push_back(Alembic::Abc::V3f(FLT_MAX, FLT_MAX, FLT_MAX));
        velocityVec.push_back(Alembic::Abc::V3f(0.0f, 0.0f, 0.0f));
        scaleVec.push_back(Alembic::Abc::V3f(1.0f, 1.0f, 1.0f));
        widthVec.push_back(0.0f);
        ageVec.push_back(0.0f);
        idVec.push_back(static_cast<uint64_t>(-1));
        orientationVec.push_back(Alembic::Abc::Quatf(0.0f, 1.0f, 0.0f, 0.0f));
        angularVelocityVec.push_back(Alembic::Abc::Quatf(0.0f, 1.0f, 0.0f, 0.0f));
    }
    else
    {
        if (constantPos)        { positionVec.resize(1); }
        if (constantVel)        { velocityVec.resize(1); }
        if (constantScale)      { scaleVec.resize(1); }
        if (constantWidth)      { widthVec.resize(1); }
        if (constantAge)        { ageVec.resize(1); }
        if (constantOrientation){ orientationVec.resize(1); }
        if (constantAngularVel) { angularVelocityVec.resize(1); }
    }

    // Store the information into our properties and points schema
    Alembic::Abc::P3fArraySample positionSample(&positionVec.front(), positionVec.size());
    Alembic::Abc::P3fArraySample velocitySample(&velocityVec.front(), velocityVec.size());
    Alembic::Abc::P3fArraySample scaleSample(&scaleVec.front(), scaleVec.size());
    Alembic::Abc::FloatArraySample widthSample(&widthVec.front(), widthVec.size());
    Alembic::Abc::FloatArraySample ageSample(&ageVec.front(), ageVec.size());
    Alembic::Abc::FloatArraySample massSample(&massVec.front(), massVec.size());
    Alembic::Abc::FloatArraySample shapeTimeSample(&shapeTimeVec.front(), shapeTimeVec.size());
    Alembic::Abc::UInt64ArraySample idSample(&idVec.front(), idVec.size());
    Alembic::Abc::UInt16ArraySample shapeTypeSample(&shapeTypeVec.front(), shapeTypeVec.size());
    Alembic::Abc::UInt16ArraySample shapeInstanceIDSample(&shapeInstanceIDVec.front(), shapeInstanceIDVec.size());
    Alembic::Abc::QuatfArraySample orientationSample(&orientationVec.front(), orientationVec.size());
    Alembic::Abc::QuatfArraySample angularVelocitySample(&angularVelocityVec.front(), angularVelocityVec.size());
    Alembic::Abc::C4fArraySample colorSample(&colorVec.front(), colorVec.size());
    Alembic::Abc::StringArraySample instanceNamesSample(&instanceNamesVec.front(), instanceNamesVec.size());

    mScaleProperty.set(scaleSample);
    mAgeProperty.set(ageSample);
    mMassProperty.set(massSample);
    mShapeTimeProperty.set(shapeTimeSample);
    mShapeTypeProperty.set(shapeTypeSample);
    mShapeInstanceIDProperty.set(shapeInstanceIDSample);
    mOrientationProperty.set(orientationSample);
    mAngularVelocityProperty.set(angularVelocitySample);
    mColorProperty.set(colorSample);
    mInstanceNamesProperty.set(instanceNamesSample);

    mPointsSample.setPositions(positionSample);
    mPointsSample.setVelocities(velocitySample);
    mPointsSample.setWidths(Alembic::AbcGeom::OFloatGeomParam::Sample(widthSample, Alembic::AbcGeom::kVertexScope));
    mPointsSample.setIds(idSample);
    mPointsSample.setSelfBounds(bbox);

    mPointsSchema.set(mPointsSample);

    mNumSamples++;

    return true;
}

// static
void AlembicPoints::ConvertMaxEulerXYZToAlembicQuat(const Point3 &degrees, Alembic::Abc::Quatf &quat)
{
    // Get the angles as a float vector of radians
    float angles[] = { DEG_TO_RAD * degrees.x, DEG_TO_RAD * degrees.y, DEG_TO_RAD * degrees.z };

    // Convert the angles to a quaternion
    Quat maxQuat;
    EulerToQuat(angles, maxQuat, EULERTYPE_XYZ);

    // Convert the quaternion to an angle and axis
    AngAxis maxAngAxis(maxQuat);

    ConvertMaxAngAxisToAlembicQuat(maxAngAxis, quat);
}

// static
void AlembicPoints::ConvertMaxAngAxisToAlembicQuat(const AngAxis &angAxis, Alembic::Abc::Quatf &quat)
{
    Point3 alembicAxis;
    ConvertMaxNormalToAlembicNormal(angAxis.axis, alembicAxis);

    quat.v.x = alembicAxis.x;
    quat.v.y = alembicAxis.y;
    quat.v.z = alembicAxis.z;
    quat.r = angAxis.angle;
}
<commit_msg>Fixing the AlembicPoints to use the new utility functions for conversions<commit_after>#include "Alembic.h"
#include "AlembicPoints.h"
#include "AlembicXform.h"
#include "SceneEntry.h"
#include "SimpObj.h"
#include "Utility.h"
#include <IParticleObjectExt.h>
#include <ParticleFlow/IParticleChannelID.h>
#include <ParticleFlow/IParticleChannelShape.h>
#include <ParticleFlow/IParticleContainer.h>
#include <ParticleFlow/IParticleGroup.h>
#include <ParticleFlow/IPFSystem.h>

namespace AbcA = ::Alembic::AbcCoreAbstract::ALEMBIC_VERSION_NS;
namespace AbcB = ::Alembic::Abc::ALEMBIC_VERSION_NS;
using namespace AbcA;
using namespace AbcB;

AlembicPoints::AlembicPoints(const SceneEntry &in_Ref, AlembicWriteJob *in_Job)
    : AlembicObject(in_Ref, in_Job)
{
    std::string pointsName = in_Ref.node->GetName();
    std::string xformName = pointsName + "Xfo";

    Alembic::AbcGeom::OXform xform(GetOParent(), xformName.c_str(), GetCurrentJob()->GetAnimatedTs());
    Alembic::AbcGeom::OPoints points(xform, pointsName.c_str(), GetCurrentJob()->GetAnimatedTs());

    // create the generic properties
    mOVisibility = CreateVisibilityProperty(points, GetCurrentJob()->GetAnimatedTs());

    mXformSchema = xform.getSchema();
    mPointsSchema = points.getSchema();

    // create all properties
    mInstanceNamesProperty = OStringArrayProperty(mPointsSchema, ".instancenames", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );

    // particle attributes
    mScaleProperty = OV3fArrayProperty(mPointsSchema, ".scale", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mOrientationProperty = OQuatfArrayProperty(mPointsSchema, ".orientation", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mAngularVelocityProperty = OQuatfArrayProperty(mPointsSchema, ".angularvelocity", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mAgeProperty = OFloatArrayProperty(mPointsSchema, ".age", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mMassProperty = OFloatArrayProperty(mPointsSchema, ".mass", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeTypeProperty = OUInt16ArrayProperty(mPointsSchema, ".shapetype", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeTimeProperty = OFloatArrayProperty(mPointsSchema, ".shapetime", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mShapeInstanceIDProperty = OUInt16ArrayProperty(mPointsSchema, ".shapeinstanceid", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
    mColorProperty = OC4fArrayProperty(mPointsSchema, ".color", mPointsSchema.getMetaData(), GetCurrentJob()->GetAnimatedTs() );
}

AlembicPoints::~AlembicPoints()
{
    // we have to clear this prior to destruction this is a workaround for issue-171
    mOVisibility.reset();
}

Alembic::Abc::OCompoundProperty AlembicPoints::GetCompound()
{
    return mPointsSchema;
}

bool AlembicPoints::Save(double time)
{
    // Note: Particles are always considered to be animated even though
    //       the node does not have the IsAnimated() flag.

    // Extract our particle emitter at the given time
    TimeValue ticks = GetTimeValueFromFrame(time);
    Object *obj = GetRef().node->EvalWorldState(ticks).obj;
    IPFSystem *particleSystem = PFSystemInterface(obj);
    if (particleSystem == NULL)
    {
        return false;
    }

    IParticleObjectExt *particlesExt = GetParticleObjectExtInterface(obj);
    if (particlesExt == NULL)
    {
        return false;
    }

    particlesExt->UpdateParticles(GetRef().node, ticks);
    int numParticles = particlesExt->NumParticles();

    // Set the visibility
    float flVisibility = GetRef().node->GetLocalVisibility(ticks);
    mOVisibility.set(flVisibility > 0 ? Alembic::AbcGeom::kVisibilityVisible : Alembic::AbcGeom::kVisibilityHidden);

    float masterScaleUnitMeters = (float)GetMasterScale(UNITS_METERS);

    // Store positions, velocity, width/size, scale, id, bounding box
    std::vector<Alembic::Abc::V3f> positionVec(numParticles);
    std::vector<Alembic::Abc::V3f> velocityVec(numParticles);
    std::vector<Alembic::Abc::V3f> scaleVec(numParticles);
    std::vector<float> widthVec(numParticles);
    std::vector<float> ageVec(numParticles);
    std::vector<float> massVec;
    std::vector<float> shapeTimeVec;
    std::vector<uint64_t> idVec(numParticles);
    std::vector<uint16_t> shapeTypeVec;
    std::vector<uint16_t> shapeInstanceIDVec;
    std::vector<Alembic::Abc::Quatf> orientationVec(numParticles);
    std::vector<Alembic::Abc::Quatf> angularVelocityVec(numParticles);
    std::vector<Alembic::Abc::C4f> colorVec;
    std::vector<std::string> instanceNamesVec;
    Alembic::Abc::Quatf orientation;
    Alembic::Abc::Quatf spin;
    Alembic::Abc::Box3d bbox;
    bool constantPos = true;
    bool constantVel = true;
    bool constantScale = true;
    bool constantWidth = true;
    bool constantAge = true;
    bool constantOrientation = true;
    bool constantAngularVel = true;

    for (int i = 0; i < numParticles; ++i)
    {
        Imath::V3f pos = ConvertMaxPointToAlembicPoint(*particlesExt->GetParticlePositionByIndex(i), masterScaleUnitMeters);
        Imath::V3f vel = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleSpeedByIndex(i), masterScaleUnitMeters, true);
        Imath::V3f scale = ConvertMaxVectorToAlembicVector(*particlesExt->GetParticleScaleXYZByIndex(i), masterScaleUnitMeters, false);
        float width = particlesExt->GetParticleScaleByIndex(i) * GetInchesToDecimetersRatio( masterScaleUnitMeters );
        TimeValue age = particlesExt->GetParticleAgeByIndex(i);
        uint64_t id = particlesExt->GetParticleBornIndex(i);
        ConvertMaxEulerXYZToAlembicQuat(*particlesExt->GetParticleOrientationByIndex(i), orientation);
        ConvertMaxAngAxisToAlembicQuat(*particlesExt->GetParticleSpinByIndex(i), spin);

        /*
        Mesh *mesh = particlesExt->GetParticleShapeByIndex(i);
        INode *particleGroupNode = particlesExt->GetParticleGroup(i);
        Object *particleGroupObj = (particleGroupNode != NULL) ? particleGroupNode->EvalWorldState(ticks).obj : NULL;
        IParticleGroup *particleGroup = GetParticleGroupInterface(particleGroupObj);
        ::IObject *particleContainerObject = (particleGroup != NULL) ? particleGroup->GetParticleContainer() : NULL;
        IParticleChannelIDR *chID = GetParticleChannelIDRInterface(particleContainerObject);
        if (chID != NULL)
        {
            id = chID->GetParticleIndex(i);
        }
        IParticleChannelMeshR *channelMesh = GetParticleChannelShapeRInterface(particleContainerObject);
        if (channelMesh != NULL)
        {
            bool isShared = channelMesh->IsShared();
            const Mesh *mesh = channelMesh->GetValue(i);
        }
        */

        positionVec[i].setValue(pos.x, pos.y, pos.z);
        velocityVec[i].setValue(vel.x, vel.y, vel.z);
        scaleVec[i].setValue(scale.x, scale.y, scale.z);
        widthVec[i] = width;
        ageVec[i] = static_cast<float>(GetSecondsFromTimeValue(age));
        idVec[i] = id;
        orientationVec[i] = orientation;
        angularVelocityVec[i] = spin;
        bbox.extendBy(positionVec[i]);

        constantPos &= (positionVec[i] == positionVec[0]);
        constantVel &= (velocityVec[i] == velocityVec[0]);
        constantScale &= (scaleVec[i] == scaleVec[0]);
        constantWidth &= (widthVec[i] == widthVec[0]);
        constantAge &= (ageVec[i] == ageVec[0]);
        constantOrientation &= (orientationVec[i] == orientationVec[0]);
        constantAngularVel &= (angularVelocityVec[i] == angularVelocityVec[0]);
    }

    // Set constant properties that are not currently supported by Max
    massVec.push_back(1.0f);
    shapeTimeVec.push_back(1.0f);
    shapeTypeVec.push_back(ShapeType_Point);
    shapeInstanceIDVec.push_back(0);
    colorVec.push_back(Alembic::Abc::C4f(0.0f, 0.0f, 0.0f, 1.0f));
    instanceNamesVec.push_back("");

    if (numParticles == 0)
    {
        positionVec.push_back(Alembic::Abc::V3f(FLT_MAX, FLT_MAX, FLT_MAX));
        velocityVec.push_back(Alembic::Abc::V3f(0.0f, 0.0f, 0.0f));
        scaleVec.push_back(Alembic::Abc::V3f(1.0f, 1.0f, 1.0f));
        widthVec.push_back(0.0f);
        ageVec.push_back(0.0f);
        idVec.push_back(static_cast<uint64_t>(-1));
        orientationVec.push_back(Alembic::Abc::Quatf(0.0f, 1.0f, 0.0f, 0.0f));
        angularVelocityVec.push_back(Alembic::Abc::Quatf(0.0f, 1.0f, 0.0f, 0.0f));
    }
    else
    {
        if (constantPos)        { positionVec.resize(1); }
        if (constantVel)        { velocityVec.resize(1); }
        if (constantScale)      { scaleVec.resize(1); }
        if (constantWidth)      { widthVec.resize(1); }
        if (constantAge)        { ageVec.resize(1); }
        if (constantOrientation){ orientationVec.resize(1); }
        if (constantAngularVel) { angularVelocityVec.resize(1); }
    }

    // Store the information into our properties and points schema
    Alembic::Abc::P3fArraySample positionSample(&positionVec.front(), positionVec.size());
    Alembic::Abc::P3fArraySample velocitySample(&velocityVec.front(), velocityVec.size());
    Alembic::Abc::P3fArraySample scaleSample(&scaleVec.front(), scaleVec.size());
    Alembic::Abc::FloatArraySample widthSample(&widthVec.front(), widthVec.size());
    Alembic::Abc::FloatArraySample ageSample(&ageVec.front(), ageVec.size());
    Alembic::Abc::FloatArraySample massSample(&massVec.front(), massVec.size());
    Alembic::Abc::FloatArraySample shapeTimeSample(&shapeTimeVec.front(), shapeTimeVec.size());
    Alembic::Abc::UInt64ArraySample idSample(&idVec.front(), idVec.size());
    Alembic::Abc::UInt16ArraySample shapeTypeSample(&shapeTypeVec.front(), shapeTypeVec.size());
    Alembic::Abc::UInt16ArraySample shapeInstanceIDSample(&shapeInstanceIDVec.front(), shapeInstanceIDVec.size());
    Alembic::Abc::QuatfArraySample orientationSample(&orientationVec.front(), orientationVec.size());
    Alembic::Abc::QuatfArraySample angularVelocitySample(&angularVelocityVec.front(), angularVelocityVec.size());
    Alembic::Abc::C4fArraySample colorSample(&colorVec.front(), colorVec.size());
    Alembic::Abc::StringArraySample instanceNamesSample(&instanceNamesVec.front(), instanceNamesVec.size());

    mScaleProperty.set(scaleSample);
    mAgeProperty.set(ageSample);
    mMassProperty.set(massSample);
    mShapeTimeProperty.set(shapeTimeSample);
    mShapeTypeProperty.set(shapeTypeSample);
    mShapeInstanceIDProperty.set(shapeInstanceIDSample);
    mOrientationProperty.set(orientationSample);
    mAngularVelocityProperty.set(angularVelocitySample);
    mColorProperty.set(colorSample);
    mInstanceNamesProperty.set(instanceNamesSample);

    mPointsSample.setPositions(positionSample);
    mPointsSample.setVelocities(velocitySample);
    mPointsSample.setWidths(Alembic::AbcGeom::OFloatGeomParam::Sample(widthSample, Alembic::AbcGeom::kVertexScope));
    mPointsSample.setIds(idSample);
    mPointsSample.setSelfBounds(bbox);

    mPointsSchema.set(mPointsSample);

    mNumSamples++;

    return true;
}

// static
void AlembicPoints::ConvertMaxEulerXYZToAlembicQuat(const Point3 &degrees, Alembic::Abc::Quatf &quat)
{
    // Get the angles as a float vector of radians
    float angles[] = { DEG_TO_RAD * degrees.x, DEG_TO_RAD * degrees.y, DEG_TO_RAD * degrees.z };

    // Convert the angles to a quaternion
    Quat maxQuat;
    EulerToQuat(angles, maxQuat, EULERTYPE_XYZ);

    // Convert the quaternion to an angle and axis
    AngAxis maxAngAxis(maxQuat);

    ConvertMaxAngAxisToAlembicQuat(maxAngAxis, quat);
}

// static
void AlembicPoints::ConvertMaxAngAxisToAlembicQuat(const AngAxis &angAxis, Alembic::Abc::Quatf &quat)
{
    Imath::V3f alembicAxis = ConvertMaxNormalToAlembicNormal(angAxis.axis);

    quat.v.x = alembicAxis.x;
    quat.v.y = alembicAxis.y;
    quat.v.z = alembicAxis.z;
    quat.r = angAxis.angle;
}
<|endoftext|>