<commit_before>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwmpplayercontrol.h"

#include "qwmpevents.h"
#include "qwmpglobal.h"
#include "qwmpmetadata.h"
#include "qwmpplaylist.h"

#include "qmediaplayer.h"
#include "qmediaplaylist.h"

#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>

QWmpPlayerControl::QWmpPlayerControl(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
        : QMediaPlayerControl(parent)
        , m_player(player)
        , m_controls(0)
        , m_settings(0)
        , m_state(QMediaPlayer::StoppedState)
        , m_duration(0)
        , m_buffering(false)
        , m_videoAvailable(false)
{
    m_player->get_controls(&m_controls);
    m_player->get_settings(&m_settings);
    m_player->get_network(&m_network);

    WMPPlayState state = wmppsUndefined;
    if (m_player->get_playState(&state) == S_OK)
        playStateChangeEvent(state);

    connect(events, SIGNAL(Buffering(VARIANT_BOOL)), this, SLOT(bufferingEvent(VARIANT_BOOL)));
    connect(events, SIGNAL(PositionChange(double,double)),
            this, SLOT(positionChangeEvent(double,double)));
    connect(events, SIGNAL(PlayStateChange(long)), this, SLOT(playStateChangeEvent(long)));
    connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
            this, SLOT(currentItemChangeEvent(IDispatch*)));
    connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
}

QWmpPlayerControl::~QWmpPlayerControl()
{
    if (m_controls) m_controls->Release();
    if (m_settings) m_settings->Release();
    if (m_network) m_network->Release();
}

QMediaPlayer::State QWmpPlayerControl::state() const
{
    return m_state;
}

QMediaPlayer::MediaStatus QWmpPlayerControl::mediaStatus() const
{
    return m_status;
}

qint64 QWmpPlayerControl::duration() const
{
    double duration = 0.;

    IWMPMedia *media = 0;
    if (m_controls && m_controls->get_currentItem(&media) == S_OK) {
        media->get_duration(&duration);

        media->Release();
    }

    return m_duration * 1000;
}

qint64 QWmpPlayerControl::position() const
{
    double position;

    if (m_controls)
        m_controls->get_currentPosition(&position);

    return position * 1000;
}

void QWmpPlayerControl::setPosition(qint64 position)
{
    if (m_controls)
        m_controls->put_currentPosition(double(position) / 1000.);
}

int QWmpPlayerControl::volume() const
{
    long volume = 0;

    if (m_settings)
        m_settings->get_volume(&volume);

    return volume;
}

void QWmpPlayerControl::setVolume(int volume)
{
    if (m_settings && m_settings->put_volume(volume) == S_OK)
        emit volumeChanged(volume);
}

bool QWmpPlayerControl::isMuted() const
{
    VARIANT_BOOL mute = FALSE;

    if (m_settings)
        m_settings->get_mute(&mute);

    return mute;
}

void QWmpPlayerControl::setMuted(bool muted)
{
    if (m_settings && m_settings->put_mute(muted ? TRUE : FALSE) == S_OK)
        emit mutingChanged(muted);

}

int QWmpPlayerControl::bufferStatus() const
{
    long progress = 0;

    if (m_network)
        m_network->get_bufferingProgress(&progress);

    return progress;
}

bool QWmpPlayerControl::isVideoAvailable() const
{
    return m_videoAvailable;
}

void QWmpPlayerControl::setVideoAvailable(bool available)
{
    if (m_videoAvailable != available)
        emit this->videoAvailabilityChanged(m_videoAvailable = available);
}

bool QWmpPlayerControl::isSeekable() const
{
    return true;
}

float QWmpPlayerControl::playbackRate() const
{
    double rate = 0.;

    if (m_settings)
        m_settings->get_rate(&rate);

    return rate;
}

void QWmpPlayerControl::setPlaybackRate(float rate)
{
    if (m_settings)
        m_settings->put_rate(rate);
}

void QWmpPlayerControl::play()
{
    if (m_controls)
        m_controls->play();
}

void QWmpPlayerControl::pause()
{
    if (m_controls)
        m_controls->pause();
}

void QWmpPlayerControl::stop()
{
    if (m_controls)
        m_controls->stop();
}

QMediaSource QWmpPlayerControl::media() const
{
    QMediaResourceList resources;

    QUrl uri = url();

    if (!uri.isEmpty())
        resources << QMediaResource(uri);

    return resources;
}

const QIODevice *mediaStream() const
{
    return 0;
}

void QWmpPlayerControl::setMedia(const QMediaSource &source, QIODevice *stream)
{
    if (!source.isNull() && !stream)
        setUrl(source.contentUri());
    else
        setUrl(QUrl());
}

void QWmpPlayerControl::bufferingEvent(VARIANT_BOOL buffering)
{
    if (m_state != QMediaPlayer::StoppedState) {
        emit mediaStatusChanged(m_status = buffering
                ? QMediaPlayer::BufferingMedia
                : QMediaPlayer::BufferedMedia);
    }
}

void QWmpPlayerControl::currentItemChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch && dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        double duration = 0;

        if (media->get_duration(&duration) == S_OK)
            emit durationChanged(duration * 1000);
    }
}

void QWmpPlayerControl::mediaChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch &&  dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        IWMPMedia *currentMedia = 0;
        if (m_controls && m_controls->get_currentItem(&currentMedia) == S_OK) {
            VARIANT_BOOL isEqual = VARIANT_FALSE;
            if (media->get_isIdentical(currentMedia, &isEqual) == S_OK && isEqual) {
                double duration = 0;

                if (media->get_duration(&duration) == S_OK)
                    emit durationChanged(duration * 1000);
            }
            currentMedia->Release();
        }
        media->Release();
    }
}

void QWmpPlayerControl::positionChangeEvent(double from, double to)
{
    Q_UNUSED(from);

    emit positionChanged(to * 1000);
}

void QWmpPlayerControl::playStateChangeEvent(long state)
{
    switch (state) {
    case wmppsUndefined:
        m_state = QMediaPlayer::StoppedState;
        m_status = QMediaPlayer::UnknownMediaStatus;

        emit stateChanged(m_state);
        emit mediaStatusChanged(m_status);
        break;
    case wmppsStopped:
        if (m_state != QMediaPlayer::StoppedState) {
            m_state = QMediaPlayer::StoppedState;
            m_status = QMediaPlayer::LoadedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        }
        break;
    case wmppsPaused:
        if (m_state != QMediaPlayer::PausedState && m_status != QMediaPlayer::BufferedMedia) {
            m_state = QMediaPlayer::PausedState;
            m_status = QMediaPlayer::BufferedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        } else if (m_state != QMediaPlayer::PausedState) {
            emit stateChanged(m_state = QMediaPlayer::PausedState);
        } else if (m_status != QMediaPlayer::BufferedMedia) {
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        }
        break;
    case wmppsPlaying:
    case wmppsScanForward:
    case wmppsScanReverse:
        if (m_state != QMediaPlayer::PlayingState && m_status != QMediaPlayer::BufferedMedia) {
            m_state = QMediaPlayer::PlayingState;
            m_status = QMediaPlayer::BufferedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        } else if (m_state != QMediaPlayer::PlayingState) {
            emit stateChanged(m_state = QMediaPlayer::PlayingState);
        } else if (m_status != QMediaPlayer::BufferedMedia) {
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        }

        if (m_state != QMediaPlayer::PlayingState)
            emit stateChanged(m_state = QMediaPlayer::PlayingState);
        if (m_status != QMediaPlayer::BufferedMedia)
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        break;
    case wmppsBuffering:
    case wmppsWaiting:
        if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState)
            emit mediaStatusChanged(m_status = QMediaPlayer::StalledMedia);
        break;
    case wmppsMediaEnded:
        if (m_status != QMediaPlayer::EndOfMedia && m_state != QMediaPlayer::StoppedState) {
            m_state = QMediaPlayer::StoppedState;
            m_status = QMediaPlayer::StalledMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        }
        break;
    case wmppsTransitioning:
        if (m_status != QMediaPlayer::LoadingMedia)
            emit mediaStatusChanged(m_status = QMediaPlayer::LoadingMedia);
        break;
    case wmppsReady:
        if (m_status != QMediaPlayer::LoadedMedia)
            m_status = m_status = QMediaPlayer::LoadedMedia;

            if (m_state != QMediaPlayer::StoppedState)
                emit stateChanged(QMediaPlayer::StoppedState);
            emit mediaStatusChanged(m_status);
        break;
    case wmppsReconnecting:
        if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState)
            emit mediaStatusChanged(m_status = QMediaPlayer::StalledMedia);
        break;
    default:
        break;
    }
}

QUrl QWmpPlayerControl::url() const
{
    BSTR string;
    if (m_player && m_player->get_URL(&string) == S_OK) {
        QUrl url(QString::fromWCharArray(string, SysStringLen(string)), QUrl::StrictMode);

        SysFreeString(string);

        return url;
    } else {
        return QUrl();
    }
}

void QWmpPlayerControl::setUrl(const QUrl &url)
{
    if (m_player) {
        BSTR string = SysAllocString(reinterpret_cast<const wchar_t *>(url.toString().unicode()));

        m_player->put_URL(string);

        SysFreeString(string);
    }
}
<commit_msg>Compile fix.<commit_after>/****************************************************************************
**
** Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** 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, Nokia gives you certain
** additional rights. These rights are described in the Nokia Qt LGPL
** Exception version 1.0, included in the file LGPL_EXCEPTION.txt in this
** package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at http://qt.nokia.com/contact.
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qwmpplayercontrol.h"

#include "qwmpevents.h"
#include "qwmpglobal.h"
#include "qwmpmetadata.h"
#include "qwmpplaylist.h"

#include "qmediaplayer.h"
#include "qmediaplaylist.h"

#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>

QWmpPlayerControl::QWmpPlayerControl(IWMPCore3 *player, QWmpEvents *events, QObject *parent)
        : QMediaPlayerControl(parent)
        , m_player(player)
        , m_controls(0)
        , m_settings(0)
        , m_state(QMediaPlayer::StoppedState)
        , m_duration(0)
        , m_buffering(false)
        , m_videoAvailable(false)
{
    m_player->get_controls(&m_controls);
    m_player->get_settings(&m_settings);
    m_player->get_network(&m_network);

    WMPPlayState state = wmppsUndefined;
    if (m_player->get_playState(&state) == S_OK)
        playStateChangeEvent(state);

    connect(events, SIGNAL(Buffering(VARIANT_BOOL)), this, SLOT(bufferingEvent(VARIANT_BOOL)));
    connect(events, SIGNAL(PositionChange(double,double)),
            this, SLOT(positionChangeEvent(double,double)));
    connect(events, SIGNAL(PlayStateChange(long)), this, SLOT(playStateChangeEvent(long)));
    connect(events, SIGNAL(CurrentItemChange(IDispatch*)),
            this, SLOT(currentItemChangeEvent(IDispatch*)));
    connect(events, SIGNAL(MediaChange(IDispatch*)), this, SLOT(mediaChangeEvent(IDispatch*)));
}

QWmpPlayerControl::~QWmpPlayerControl()
{
    if (m_controls) m_controls->Release();
    if (m_settings) m_settings->Release();
    if (m_network) m_network->Release();
}

QMediaPlayer::State QWmpPlayerControl::state() const
{
    return m_state;
}

QMediaPlayer::MediaStatus QWmpPlayerControl::mediaStatus() const
{
    return m_status;
}

qint64 QWmpPlayerControl::duration() const
{
    double duration = 0.;

    IWMPMedia *media = 0;
    if (m_controls && m_controls->get_currentItem(&media) == S_OK) {
        media->get_duration(&duration);

        media->Release();
    }

    return m_duration * 1000;
}

qint64 QWmpPlayerControl::position() const
{
    double position;

    if (m_controls)
        m_controls->get_currentPosition(&position);

    return position * 1000;
}

void QWmpPlayerControl::setPosition(qint64 position)
{
    if (m_controls)
        m_controls->put_currentPosition(double(position) / 1000.);
}

int QWmpPlayerControl::volume() const
{
    long volume = 0;

    if (m_settings)
        m_settings->get_volume(&volume);

    return volume;
}

void QWmpPlayerControl::setVolume(int volume)
{
    if (m_settings && m_settings->put_volume(volume) == S_OK)
        emit volumeChanged(volume);
}

bool QWmpPlayerControl::isMuted() const
{
    VARIANT_BOOL mute = FALSE;

    if (m_settings)
        m_settings->get_mute(&mute);

    return mute;
}

void QWmpPlayerControl::setMuted(bool muted)
{
    if (m_settings && m_settings->put_mute(muted ? TRUE : FALSE) == S_OK)
        emit mutingChanged(muted);

}

int QWmpPlayerControl::bufferStatus() const
{
    long progress = 0;

    if (m_network)
        m_network->get_bufferingProgress(&progress);

    return progress;
}

bool QWmpPlayerControl::isVideoAvailable() const
{
    return m_videoAvailable;
}

void QWmpPlayerControl::setVideoAvailable(bool available)
{
    if (m_videoAvailable != available)
        emit this->videoAvailabilityChanged(m_videoAvailable = available);
}

bool QWmpPlayerControl::isSeekable() const
{
    return true;
}

float QWmpPlayerControl::playbackRate() const
{
    double rate = 0.;

    if (m_settings)
        m_settings->get_rate(&rate);

    return rate;
}

void QWmpPlayerControl::setPlaybackRate(float rate)
{
    if (m_settings)
        m_settings->put_rate(rate);
}

void QWmpPlayerControl::play()
{
    if (m_controls)
        m_controls->play();
}

void QWmpPlayerControl::pause()
{
    if (m_controls)
        m_controls->pause();
}

void QWmpPlayerControl::stop()
{
    if (m_controls)
        m_controls->stop();
}

QMediaSource QWmpPlayerControl::media() const
{
    QMediaResourceList resources;

    QUrl uri = url();

    if (!uri.isEmpty())
        resources << QMediaResource(uri);

    return resources;
}

const QIODevice *QWmpPlayerControl::mediaStream() const
{
    return 0;
}

void QWmpPlayerControl::setMedia(const QMediaSource &source, QIODevice *stream)
{
    if (!source.isNull() && !stream)
        setUrl(source.contentUri());
    else
        setUrl(QUrl());
}

void QWmpPlayerControl::bufferingEvent(VARIANT_BOOL buffering)
{
    if (m_state != QMediaPlayer::StoppedState) {
        emit mediaStatusChanged(m_status = buffering
                ? QMediaPlayer::BufferingMedia
                : QMediaPlayer::BufferedMedia);
    }
}

void QWmpPlayerControl::currentItemChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch && dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        double duration = 0;

        if (media->get_duration(&duration) == S_OK)
            emit durationChanged(duration * 1000);
    }
}

void QWmpPlayerControl::mediaChangeEvent(IDispatch *dispatch)
{
    IWMPMedia *media = 0;
    if (dispatch &&  dispatch->QueryInterface(
            __uuidof(IWMPMedia), reinterpret_cast<void **>(&media)) == S_OK) {
        IWMPMedia *currentMedia = 0;
        if (m_controls && m_controls->get_currentItem(&currentMedia) == S_OK) {
            VARIANT_BOOL isEqual = VARIANT_FALSE;
            if (media->get_isIdentical(currentMedia, &isEqual) == S_OK && isEqual) {
                double duration = 0;

                if (media->get_duration(&duration) == S_OK)
                    emit durationChanged(duration * 1000);
            }
            currentMedia->Release();
        }
        media->Release();
    }
}

void QWmpPlayerControl::positionChangeEvent(double from, double to)
{
    Q_UNUSED(from);

    emit positionChanged(to * 1000);
}

void QWmpPlayerControl::playStateChangeEvent(long state)
{
    switch (state) {
    case wmppsUndefined:
        m_state = QMediaPlayer::StoppedState;
        m_status = QMediaPlayer::UnknownMediaStatus;

        emit stateChanged(m_state);
        emit mediaStatusChanged(m_status);
        break;
    case wmppsStopped:
        if (m_state != QMediaPlayer::StoppedState) {
            m_state = QMediaPlayer::StoppedState;
            m_status = QMediaPlayer::LoadedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        }
        break;
    case wmppsPaused:
        if (m_state != QMediaPlayer::PausedState && m_status != QMediaPlayer::BufferedMedia) {
            m_state = QMediaPlayer::PausedState;
            m_status = QMediaPlayer::BufferedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        } else if (m_state != QMediaPlayer::PausedState) {
            emit stateChanged(m_state = QMediaPlayer::PausedState);
        } else if (m_status != QMediaPlayer::BufferedMedia) {
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        }
        break;
    case wmppsPlaying:
    case wmppsScanForward:
    case wmppsScanReverse:
        if (m_state != QMediaPlayer::PlayingState && m_status != QMediaPlayer::BufferedMedia) {
            m_state = QMediaPlayer::PlayingState;
            m_status = QMediaPlayer::BufferedMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        } else if (m_state != QMediaPlayer::PlayingState) {
            emit stateChanged(m_state = QMediaPlayer::PlayingState);
        } else if (m_status != QMediaPlayer::BufferedMedia) {
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        }

        if (m_state != QMediaPlayer::PlayingState)
            emit stateChanged(m_state = QMediaPlayer::PlayingState);
        if (m_status != QMediaPlayer::BufferedMedia)
            emit mediaStatusChanged(m_status = QMediaPlayer::BufferedMedia);
        break;
    case wmppsBuffering:
    case wmppsWaiting:
        if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState)
            emit mediaStatusChanged(m_status = QMediaPlayer::StalledMedia);
        break;
    case wmppsMediaEnded:
        if (m_status != QMediaPlayer::EndOfMedia && m_state != QMediaPlayer::StoppedState) {
            m_state = QMediaPlayer::StoppedState;
            m_status = QMediaPlayer::StalledMedia;

            emit stateChanged(m_state);
            emit mediaStatusChanged(m_status);
        }
        break;
    case wmppsTransitioning:
        if (m_status != QMediaPlayer::LoadingMedia)
            emit mediaStatusChanged(m_status = QMediaPlayer::LoadingMedia);
        break;
    case wmppsReady:
        if (m_status != QMediaPlayer::LoadedMedia)
            m_status = m_status = QMediaPlayer::LoadedMedia;

            if (m_state != QMediaPlayer::StoppedState)
                emit stateChanged(QMediaPlayer::StoppedState);
            emit mediaStatusChanged(m_status);
        break;
    case wmppsReconnecting:
        if (m_status != QMediaPlayer::StalledMedia && m_state != QMediaPlayer::StoppedState)
            emit mediaStatusChanged(m_status = QMediaPlayer::StalledMedia);
        break;
    default:
        break;
    }
}

QUrl QWmpPlayerControl::url() const
{
    BSTR string;
    if (m_player && m_player->get_URL(&string) == S_OK) {
        QUrl url(QString::fromWCharArray(string, SysStringLen(string)), QUrl::StrictMode);

        SysFreeString(string);

        return url;
    } else {
        return QUrl();
    }
}

void QWmpPlayerControl::setUrl(const QUrl &url)
{
    if (m_player) {
        BSTR string = SysAllocString(reinterpret_cast<const wchar_t *>(url.toString().unicode()));

        m_player->put_URL(string);

        SysFreeString(string);
    }
}
<|endoftext|>


<commit_before>//Jordan Cazamias
//9-19-2012

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <assert.h>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[]) {

	ifstream input;
	stringstream ss;
	const int IGNORE_LINES = 3; //Number of initial lines to ignore
	const string DELIM = "*"; //String to divide test data

	input.open("temp.txt");

	vector<string> names;
	vector<double> times;

	//If no revision number, retrieve column names
	if(argc <= 1)
	{
		string curr_line;

		//Ignore first n lines + delimeter- they don't hold any useful data
		for(int i = 0; i < IGNORE_LINES + 1; i++)
		{
			getline(input, curr_line);
		}

		while(!input.eof()) {

			getline(input, curr_line);
			if(curr_line == "")
				continue;
			if(curr_line == DELIM)
				break;

			////cout << "curr line: " << curr_line << endl;
			//Looking for the string after the '|' and ' '
			int first_char = 0;
			if(curr_line[0] == '|')
				first_char++;
			if (curr_line[1] == ' ')
				first_char++;

			////cout << "first char at pos: " << first_char << endl;

			//Test case: char at position first_char is a letter
			assert(isalpha(curr_line[first_char]));

			//Find end of string
			int num_chars = 0;
			while(curr_line[first_char + num_chars] != '|')
				num_chars++;

			num_chars--;

			while(curr_line[first_char + num_chars] == ' ')
			  num_chars--;

			names.push_back(curr_line.substr(first_char, num_chars+1));
		}
	}

	else //Else, extract execution time from each line
	{

		int time_index = 0;

		while(!input.eof())
		{

			string curr_line = "";

			//Read in line
			getline(input,curr_line);

			//Check for delimeter
			if(curr_line == DELIM)
			{
				////cout << "Delimeter detected" << endl;
				time_index = 0;
				//Ignore first n lines- they don't hold any useful data
				for(int i = 0; i < IGNORE_LINES; i++)
				{
					string dummy;
					getline(input, dummy);
					////cout << "Skipping: " << dummy << endl;
				}
				continue;
			}

			////cout << "Reading: " << curr_line << endl;

			if(curr_line == "" && DELIM != "")
				continue;

			//Looking for a number that ends with 's'
			int last_s = curr_line.rfind('s');
			//In case 's' is not used in the future
			assert(isdigit(curr_line[last_s - 1])); // Test: s preceded by number

			//Find time string and convert to double
			int num_start = last_s - 1;
				while(curr_line[num_start] != ' ')
				num_start--;
			string timestr = curr_line.substr(num_start+1, last_s - num_start);
			double time = (double)atof(timestr.substr(0,timestr.size()-1).c_str());

			assert(times.size() >= time_index);
			// first addition of times to vector; each loop, times.size() should be one less than time_index
			if(times.size() == time_index)
				times.push_back(time);
			else
				times[time_index] = (time < times[time_index]) ? time : times[time_index]; //else, determines minimum time and stores it
			time_index++;

		}
	}

	//Output individual names
	if(argc <= 1) {
		for(int i = 0; i < names.size(); i++) {
			cout << names[i];
			if(i < names.size() - 1)
				cout << endl;
		}
	}

	//Output individual times
	if(argc > 1) {
		cout << argv[1];
		for(int i = 0; i < times.size(); i++)
			cout << " " << times[i];
	}

	cout << endl;

	return 0;
}
<commit_msg>benchmark: make parser more robust<commit_after>//Jordan Cazamias
//9-19-2012

#include <iostream>
#include <string>
#include <sstream>
#include <fstream>
#include <vector>
#include <assert.h>
#include <stdlib.h>

using namespace std;

int main(int argc, char *argv[]) {

	ifstream input;
	stringstream ss;
	const int IGNORE_LINES = 3; //Number of initial lines to ignore
	const string DELIM = "*"; //String to divide test data

	input.open("temp.txt");

	vector<string> names;
	vector<double> times;

	//If no revision number, retrieve column names
	if(argc <= 1)
	{
		string curr_line;

		//Ignore first n lines + delimeter- they don't hold any useful data
		for(int i = 0; i < IGNORE_LINES + 1; i++)
		{
			getline(input, curr_line);
		}

		while(!input.eof()) {

			getline(input, curr_line);
			if(curr_line == "")
				continue;
			if(curr_line == DELIM)
				break;

			////cout << "curr line: " << curr_line << endl;
			//Looking for the string after the '|' and ' '
			int first_char = 0;
			if(curr_line[0] == '|')
				first_char++;
			if (curr_line[1] == ' ')
				first_char++;

			////cout << "first char at pos: " << first_char << endl;

			//Find end of string
			int num_chars = 0;
			while(curr_line[first_char + num_chars] != '|')
				num_chars++;

			num_chars--;

			while(curr_line[first_char + num_chars] == ' ')
			  num_chars--;

			names.push_back(curr_line.substr(first_char, num_chars+1));
		}
	}

	else //Else, extract execution time from each line
	{

		int time_index = 0;

		while(!input.eof())
		{

			string curr_line = "";

			//Read in line
			getline(input,curr_line);

			//Check for delimeter
			if(curr_line == DELIM)
			{
				////cout << "Delimeter detected" << endl;
				time_index = 0;
				//Ignore first n lines- they don't hold any useful data
				for(int i = 0; i < IGNORE_LINES; i++)
				{
					string dummy;
					getline(input, dummy);
					////cout << "Skipping: " << dummy << endl;
				}
				continue;
			}

			////cout << "Reading: " << curr_line << endl;

			if(curr_line == "" && DELIM != "")
				continue;

			//Looking for a number that ends with 's'
			int last_s = curr_line.rfind('s');
			//In case 's' is not used in the future
			assert(isdigit(curr_line[last_s - 1])); // Test: s preceded by number

			//Find time string and convert to double
			int num_start = last_s - 1;
				while(curr_line[num_start] != ' ')
				num_start--;
			string timestr = curr_line.substr(num_start+1, last_s - num_start);
			double time = (double)atof(timestr.substr(0,timestr.size()-1).c_str());

			assert(times.size() >= time_index);
			// first addition of times to vector; each loop, times.size() should be one less than time_index
			if(times.size() == time_index)
				times.push_back(time);
			else
				times[time_index] = (time < times[time_index]) ? time : times[time_index]; //else, determines minimum time and stores it
			time_index++;

		}
	}

	//Output individual names
	if(argc <= 1) {
		for(int i = 0; i < names.size(); i++) {
			cout << names[i];
			if(i < names.size() - 1)
				cout << endl;
		}
	}

	//Output individual times
	if(argc > 1) {
		cout << argv[1];
		for(int i = 0; i < times.size(); i++)
			cout << " " << times[i];
	}

	cout << endl;

	return 0;
}
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>

void a(){
    printf("Hola\n");
}

void f(){
    int variable;
    f();
    a();
}

int main(int argc, char *argv[]){

    f();
    return EXIT_SUCCESS;
}

/*
 *     +------+
 *     | main |
 *     |  o   |
 *     +--+---+
 *        |
 *        V
 *   +----------+
 *   |     f    |<+
 *   +----------+ X
 *   | variable | |
 *   |        o-+-+
 *   |    o-----+---+
 * +-+-> a()    |   |
 * | +----+-----+   |
 * |      |         |
 * |      V         |
 * | +----------+   |
 * | |     f    |<--+
 * | +----------+
 * | | variable |
 * +||          |
 *   +----------+
 */
<commit_msg>Delete variables.cpp<commit_after><|endoftext|>


<commit_before>#include <utility>

#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>

#include "utils.h"

namespace rpc {

void* ThreadPool::start_thread_pool(void* args) {
    std::pair<ThreadPool*, int>* thread_args = (std::pair<ThreadPool*, int>*) args;
    ThreadPool* threadpool = thread_args->first;
    int tid = thread_args->second;
    delete thread_args;

    threadpool->run_thread(tid);

    pthread_exit(NULL);
    return NULL;
}

ThreadPool::ThreadPool(int n /* =... */)
        : n_(n) {
    th_ = new pthread_t[n_];
    q_ = new Queue<Runnable*> [n_];

    for (int i = 0; i < n_; i++) {
        std::pair<ThreadPool*, int>* thread_args = new std::pair<ThreadPool*, int>;
        thread_args->first = this;
        thread_args->second = i;
        Pthread_create(&th_[i], NULL, ThreadPool::start_thread_pool, thread_args);
    }
}

ThreadPool::~ThreadPool() {
    for (int i = 0; i < n_; i++) {
        q_[i].push(NULL);	// NULL is used as a termination token
    }
    for (int i = 0; i < n_; i++) {
        Pthread_join(th_[i], NULL);
    }
    delete[] th_;
    delete[] q_;
}

void ThreadPool::run_async(Runnable* r) {
    verify(r != NULL);
    // NULL is used to terminate a thread

    // Randomly select a thread for the job.
    // There could be better schedule policy.
    int queue_id = rand() % n_;
    q_[queue_id].push(r);
}

void ThreadPool::run_async(const std::function<void()>& f) {
    class R: public Runnable {
        std::function<void()> f_;
    public:
        R(const std::function<void()>& f): f_(f) {
            printf("sizeof(f)=%d\n", sizeof(f));
        }
        void run() {
            f_();
        }
    };
    run_async(new R(f));
}

void ThreadPool::run_thread(int tid) {
    for (;;) {
        Runnable* j = q_[tid].pop();
        if (j == NULL) {
            return;
        }
        j->run();
        delete j;
    }
}

int Log::level = Log::DEBUG;
FILE* Log::fp = stdout;
pthread_mutex_t Log::m = PTHREAD_MUTEX_INITIALIZER;

void Log::set_level(int level) {
    Pthread_mutex_lock(&Log::m);
    Log::level = level;
    Pthread_mutex_unlock(&Log::m);
}

void Log::set_file(FILE* fp) {
    verify(fp != NULL);
    Pthread_mutex_lock(&Log::m);
    Log::fp = fp;
    Pthread_mutex_unlock(&Log::m);
}

void Log::log_v(int level, const char* fmt, va_list args) {
    static char indicator[] = { 'F', 'E', 'W', 'I', 'D' };
    assert(level <= Log::DEBUG);
    if (level <= Log::level) {
        Pthread_mutex_lock(&Log::m);
        fprintf(Log::fp, "%c: ", indicator[level]);
        vfprintf(Log::fp, fmt, args);
        fprintf(Log::fp, "\n");
        fflush(Log::fp);
        Pthread_mutex_unlock(&Log::m);
    }
}

void Log::log(int level, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(level, fmt, args);
    va_end(args);
}

void Log::fatal(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, fmt, args);
    va_end(args);
}

void Log::error(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, fmt, args);
    va_end(args);
}

void Log::warn(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, fmt, args);
    va_end(args);
}

void Log::info(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, fmt, args);
    va_end(args);
}

void Log::debug(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, fmt, args);
    va_end(args);
}

int set_nonblocking(int fd, bool nonblocking) {
    int ret = fcntl(fd, F_GETFL, 0);
    if (ret != -1) {
        if (nonblocking) {
            ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
        } else {
            ret = fcntl(fd, F_SETFL, ret & ~O_NONBLOCK);
        }
    }
    return ret;
}

Timer::Timer() {
  reset();
}

void Timer::reset() {
  start_.tv_sec = 0;
  start_.tv_usec = 0;
  end_.tv_sec = 0;
  end_.tv_usec = 0;
}

void Timer::start() {
  gettimeofday(&start_, NULL);
}

void Timer::end() {
  gettimeofday(&end_, NULL);
}

double Timer::elapsed() const {
  // assumes end_ >= start_

  double sec = 0;
  double usec = 0;
  if (end_.tv_usec < start_.tv_usec) {
    sec = end_.tv_sec - 1 - start_.tv_sec;
    usec = (end_.tv_usec + 1000000 - start_.tv_usec) / 1000000.0;
  } else {
    sec = end_.tv_sec - start_.tv_sec;
    usec = (end_.tv_usec - start_.tv_usec) / 1000000.0;
  }
  return sec+usec;
}

}
<commit_msg>minor modification<commit_after>#include <utility>

#include <fcntl.h>
#include <stdlib.h>
#include <sys/time.h>

#include "utils.h"

namespace rpc {

void* ThreadPool::start_thread_pool(void* args) {
    std::pair<ThreadPool*, int>* thread_args = (std::pair<ThreadPool*, int>*) args;
    ThreadPool* threadpool = thread_args->first;
    int tid = thread_args->second;
    delete thread_args;

    threadpool->run_thread(tid);

    pthread_exit(NULL);
    return NULL;
}

ThreadPool::ThreadPool(int n /* =... */)
        : n_(n) {
    th_ = new pthread_t[n_];
    q_ = new Queue<Runnable*> [n_];

    for (int i = 0; i < n_; i++) {
        std::pair<ThreadPool*, int>* thread_args = new std::pair<ThreadPool*, int>;
        thread_args->first = this;
        thread_args->second = i;
        Pthread_create(&th_[i], NULL, ThreadPool::start_thread_pool, thread_args);
    }
}

ThreadPool::~ThreadPool() {
    for (int i = 0; i < n_; i++) {
        q_[i].push(NULL);	// NULL is used as a termination token
    }
    for (int i = 0; i < n_; i++) {
        Pthread_join(th_[i], NULL);
    }
    delete[] th_;
    delete[] q_;
}

void ThreadPool::run_async(Runnable* r) {
    verify(r != NULL);
    // NULL is used to terminate a thread

    // Randomly select a thread for the job.
    // There could be better schedule policy.
    int queue_id = rand() % n_;
    q_[queue_id].push(r);
}

void ThreadPool::run_async(const std::function<void()>& f) {
    class R: public Runnable {
        std::function<void()> f_;
    public:
        R(const std::function<void()>& f): f_(f) {}
        void run() {
            f_();
        }
    };
    run_async(new R(f));
}

void ThreadPool::run_thread(int tid) {
    for (;;) {
        Runnable* j = q_[tid].pop();
        if (j == NULL) {
            return;
        }
        j->run();
        delete j;
    }
}

int Log::level = Log::DEBUG;
FILE* Log::fp = stdout;
pthread_mutex_t Log::m = PTHREAD_MUTEX_INITIALIZER;

void Log::set_level(int level) {
    Pthread_mutex_lock(&Log::m);
    Log::level = level;
    Pthread_mutex_unlock(&Log::m);
}

void Log::set_file(FILE* fp) {
    verify(fp != NULL);
    Pthread_mutex_lock(&Log::m);
    Log::fp = fp;
    Pthread_mutex_unlock(&Log::m);
}

void Log::log_v(int level, const char* fmt, va_list args) {
    static char indicator[] = { 'F', 'E', 'W', 'I', 'D' };
    assert(level <= Log::DEBUG);
    if (level <= Log::level) {
        Pthread_mutex_lock(&Log::m);
        fprintf(Log::fp, "%c: ", indicator[level]);
        vfprintf(Log::fp, fmt, args);
        fprintf(Log::fp, "\n");
        fflush(Log::fp);
        Pthread_mutex_unlock(&Log::m);
    }
}

void Log::log(int level, const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(level, fmt, args);
    va_end(args);
}

void Log::fatal(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::FATAL, fmt, args);
    va_end(args);
}

void Log::error(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::ERROR, fmt, args);
    va_end(args);
}

void Log::warn(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::WARN, fmt, args);
    va_end(args);
}

void Log::info(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::INFO, fmt, args);
    va_end(args);
}

void Log::debug(const char* fmt, ...) {
    va_list args;
    va_start(args, fmt);
    log_v(Log::DEBUG, fmt, args);
    va_end(args);
}

int set_nonblocking(int fd, bool nonblocking) {
    int ret = fcntl(fd, F_GETFL, 0);
    if (ret != -1) {
        if (nonblocking) {
            ret = fcntl(fd, F_SETFL, ret | O_NONBLOCK);
        } else {
            ret = fcntl(fd, F_SETFL, ret & ~O_NONBLOCK);
        }
    }
    return ret;
}

Timer::Timer() {
  reset();
}

void Timer::reset() {
  start_.tv_sec = 0;
  start_.tv_usec = 0;
  end_.tv_sec = 0;
  end_.tv_usec = 0;
}

void Timer::start() {
  gettimeofday(&start_, NULL);
}

void Timer::end() {
  gettimeofday(&end_, NULL);
}

double Timer::elapsed() const {
  // assumes end_ >= start_

  double sec = 0;
  double usec = 0;
  if (end_.tv_usec < start_.tv_usec) {
    sec = end_.tv_sec - 1 - start_.tv_sec;
    usec = (end_.tv_usec + 1000000 - start_.tv_usec) / 1000000.0;
  } else {
    sec = end_.tv_sec - start_.tv_sec;
    usec = (end_.tv_usec - start_.tv_usec) / 1000000.0;
  }
  return sec+usec;
}

}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: vtablefactory.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: obo $ $Date: 2006-09-16 15:56:54 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"

#include "bridges/cpp_uno/shared/vtablefactory.hxx"

#include "guardedarray.hxx"

#include "bridges/cpp_uno/shared/vtables.hxx"

#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "rtl/alloc.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"

#include <hash_map>
#include <new>
#include <vector>

#if defined SAL_UNX
#include <unistd.h>
#include <sys/mman.h>
#elif defined SAL_W32
#define WIN32_LEAN_AND_MEAN
#pragma warning(push,1) // disable warnings within system headers
#include <windows.h>
#pragma warning(pop)
#else
#error Unsupported platform
#endif

using bridges::cpp_uno::shared::VtableFactory;

namespace {

extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
    sal_Size pagesize;
#if defined SAL_UNX
#if defined FREEBSD || defined NETBSD
    pagesize = getpagesize();
#else
    pagesize = sysconf(_SC_PAGESIZE);
#endif
#elif defined SAL_W32
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    pagesize = info.dwPageSize;
#endif
    sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
    void * p;
#if defined SAL_UNX
    p = mmap(
        0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
        0);
    if (p == MAP_FAILED) {
        p = 0;
    }
    else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
    {
        munmap (static_cast<char*>(p), n);
        p = 0;
    }
#elif defined SAL_W32
    p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#endif
    if (p != 0) {
        *size = n;
    }
    return p;
}

extern "C" void SAL_CALL freeExec(
    rtl_arena_type *, void * address, sal_Size size)
{
#if defined SAL_UNX
    munmap(static_cast< char * >(address), size);
#elif defined SAL_W32
    (void) size; // unused
    VirtualFree(address, 0, MEM_RELEASE);
#endif
}

}

class VtableFactory::GuardedBlocks: public std::vector< Block > {
public:
    GuardedBlocks(VtableFactory const & factory):
        m_factory(factory), m_guarded(true) {}

    ~GuardedBlocks();

    void unguard() { m_guarded = false; }

private:
    GuardedBlocks(GuardedBlocks &); // not implemented
    void operator =(GuardedBlocks); // not implemented

    VtableFactory const & m_factory;
    bool m_guarded;
};

VtableFactory::GuardedBlocks::~GuardedBlocks() {
    if (m_guarded) {
        for (iterator i(begin()); i != end(); ++i) {
            m_factory.freeBlock(*i);
        }
    }
}

class VtableFactory::BaseOffset {
public:
    BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }

    sal_Int32 getFunctionOffset(rtl::OUString const & name) const
    { return m_map.find(name)->second; }

private:
    sal_Int32 calculate(
        typelib_InterfaceTypeDescription * type, sal_Int32 offset);

    typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;

    Map m_map;
};

sal_Int32 VtableFactory::BaseOffset::calculate(
    typelib_InterfaceTypeDescription * type, sal_Int32 offset)
{
    rtl::OUString name(type->aBase.pTypeName);
    if (m_map.find(name) == m_map.end()) {
        for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
            offset = calculate(type->ppBaseTypes[i], offset);
        }
        m_map.insert(Map::value_type(name, offset));
        typelib_typedescription_complete(
            reinterpret_cast< typelib_TypeDescription ** >(&type));
        offset += bridges::cpp_uno::shared::getLocalFunctions(type);
    }
    return offset;
}

VtableFactory::VtableFactory(): m_arena(
    rtl_arena_create(
        "bridges::cpp_uno::shared::VtableFactory",
        sizeof (void *), // to satisfy alignment requirements
        0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
{
    if (m_arena == 0) {
        throw std::bad_alloc();
    }
}

VtableFactory::~VtableFactory() {
    {
        osl::MutexGuard guard(m_mutex);
        for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
            for (sal_Int32 j = 0; j < i->second.count; ++j) {
                freeBlock(i->second.blocks[j]);
            }
            delete[] i->second.blocks;
        }
    }
    rtl_arena_destroy(m_arena);
}

VtableFactory::Vtables VtableFactory::getVtables(
    typelib_InterfaceTypeDescription * type)
{
    rtl::OUString name(type->aBase.pTypeName);
    osl::MutexGuard guard(m_mutex);
    Map::iterator i(m_map.find(name));
    if (i == m_map.end()) {
        GuardedBlocks blocks(*this);
        createVtables(blocks, BaseOffset(type), type, true);
        Vtables vtables;
        OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
        vtables.count = static_cast< sal_Int32 >(blocks.size());
        bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
            new Block[vtables.count]);
        vtables.blocks = guardedBlocks.get();
        for (sal_Int32 j = 0; j < vtables.count; ++j) {
            vtables.blocks[j] = blocks[j];
        }
        i = m_map.insert(Map::value_type(name, vtables)).first;
        guardedBlocks.release();
        blocks.unguard();
    }
    return i->second;
}

void VtableFactory::freeBlock(Block const & block) const {
    rtl_arena_free(m_arena, block.start, block.size);
}

void VtableFactory::createVtables(
    GuardedBlocks & blocks, BaseOffset const & baseOffset,
    typelib_InterfaceTypeDescription * type, bool includePrimary) const
{
    if (includePrimary) {
        sal_Int32 slotCount
            = bridges::cpp_uno::shared::getPrimaryFunctions(type);
        Block block;
        block.size = getBlockSize(slotCount);
        block.start = rtl_arena_alloc(m_arena, &block.size);
        if (block.start == 0) {
            throw std::bad_alloc();
        }
        try {
            void ** slots = initializeBlock(block.start) + slotCount;
            unsigned char * codeBegin =
                reinterpret_cast< unsigned char * >(slots);
            unsigned char * code = codeBegin;
            sal_Int32 vtableOffset = blocks.size() * sizeof (void **);
            for (typelib_InterfaceTypeDescription const * type2 = type;
                 type2 != 0; type2 = type2->pBaseTypeDescription)
            {
                sal_Int32 functionCount
                    = bridges::cpp_uno::shared::getLocalFunctions(type2);
                slots -= functionCount;
                code = addLocalFunctions(
                    slots, code, type2,
                    baseOffset.getFunctionOffset(type2->aBase.pTypeName),
                    functionCount, vtableOffset);
            }
            flushCode(codeBegin, code);
            blocks.push_back(block);
        } catch (...) {
            freeBlock(block);
            throw;
        }
    }
    for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
        createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
    }
}
<commit_msg>INTEGRATION: CWS mingwport06 (1.7.58); FILE MERGED 2007/08/24 12:55:23 vg 1.7.58.1: #i75499# pragma is for MSVC<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: vtablefactory.cxx,v $
 *
 *  $Revision: 1.8 $
 *
 *  last change: $Author: kz $ $Date: 2007-09-06 13:43:01 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_bridges.hxx"

#include "bridges/cpp_uno/shared/vtablefactory.hxx"

#include "guardedarray.hxx"

#include "bridges/cpp_uno/shared/vtables.hxx"

#include "osl/diagnose.h"
#include "osl/mutex.hxx"
#include "rtl/alloc.h"
#include "rtl/ustring.hxx"
#include "sal/types.h"
#include "typelib/typedescription.hxx"

#include <hash_map>
#include <new>
#include <vector>

#if defined SAL_UNX
#include <unistd.h>
#include <sys/mman.h>
#elif defined SAL_W32
#define WIN32_LEAN_AND_MEAN
#ifdef _MSC_VER
#pragma warning(push,1) // disable warnings within system headers
#endif
#include <windows.h>
#ifdef _MSC_VER
#pragma warning(pop)
#endif
#else
#error Unsupported platform
#endif

using bridges::cpp_uno::shared::VtableFactory;

namespace {

extern "C" void * SAL_CALL allocExec(rtl_arena_type *, sal_Size * size) {
    sal_Size pagesize;
#if defined SAL_UNX
#if defined FREEBSD || defined NETBSD
    pagesize = getpagesize();
#else
    pagesize = sysconf(_SC_PAGESIZE);
#endif
#elif defined SAL_W32
    SYSTEM_INFO info;
    GetSystemInfo(&info);
    pagesize = info.dwPageSize;
#endif
    sal_Size n = (*size + (pagesize - 1)) & ~(pagesize - 1);
    void * p;
#if defined SAL_UNX
    p = mmap(
        0, n, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1,
        0);
    if (p == MAP_FAILED) {
        p = 0;
    }
    else if (mprotect (static_cast<char*>(p), n, PROT_READ | PROT_WRITE | PROT_EXEC) == -1)
    {
        munmap (static_cast<char*>(p), n);
        p = 0;
    }
#elif defined SAL_W32
    p = VirtualAlloc(0, n, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
#endif
    if (p != 0) {
        *size = n;
    }
    return p;
}

extern "C" void SAL_CALL freeExec(
    rtl_arena_type *, void * address, sal_Size size)
{
#if defined SAL_UNX
    munmap(static_cast< char * >(address), size);
#elif defined SAL_W32
    (void) size; // unused
    VirtualFree(address, 0, MEM_RELEASE);
#endif
}

}

class VtableFactory::GuardedBlocks: public std::vector< Block > {
public:
    GuardedBlocks(VtableFactory const & factory):
        m_factory(factory), m_guarded(true) {}

    ~GuardedBlocks();

    void unguard() { m_guarded = false; }

private:
    GuardedBlocks(GuardedBlocks &); // not implemented
    void operator =(GuardedBlocks); // not implemented

    VtableFactory const & m_factory;
    bool m_guarded;
};

VtableFactory::GuardedBlocks::~GuardedBlocks() {
    if (m_guarded) {
        for (iterator i(begin()); i != end(); ++i) {
            m_factory.freeBlock(*i);
        }
    }
}

class VtableFactory::BaseOffset {
public:
    BaseOffset(typelib_InterfaceTypeDescription * type) { calculate(type, 0); }

    sal_Int32 getFunctionOffset(rtl::OUString const & name) const
    { return m_map.find(name)->second; }

private:
    sal_Int32 calculate(
        typelib_InterfaceTypeDescription * type, sal_Int32 offset);

    typedef std::hash_map< rtl::OUString, sal_Int32, rtl::OUStringHash > Map;

    Map m_map;
};

sal_Int32 VtableFactory::BaseOffset::calculate(
    typelib_InterfaceTypeDescription * type, sal_Int32 offset)
{
    rtl::OUString name(type->aBase.pTypeName);
    if (m_map.find(name) == m_map.end()) {
        for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
            offset = calculate(type->ppBaseTypes[i], offset);
        }
        m_map.insert(Map::value_type(name, offset));
        typelib_typedescription_complete(
            reinterpret_cast< typelib_TypeDescription ** >(&type));
        offset += bridges::cpp_uno::shared::getLocalFunctions(type);
    }
    return offset;
}

VtableFactory::VtableFactory(): m_arena(
    rtl_arena_create(
        "bridges::cpp_uno::shared::VtableFactory",
        sizeof (void *), // to satisfy alignment requirements
        0, reinterpret_cast< rtl_arena_type * >(-1), allocExec, freeExec, 0))
{
    if (m_arena == 0) {
        throw std::bad_alloc();
    }
}

VtableFactory::~VtableFactory() {
    {
        osl::MutexGuard guard(m_mutex);
        for (Map::iterator i(m_map.begin()); i != m_map.end(); ++i) {
            for (sal_Int32 j = 0; j < i->second.count; ++j) {
                freeBlock(i->second.blocks[j]);
            }
            delete[] i->second.blocks;
        }
    }
    rtl_arena_destroy(m_arena);
}

VtableFactory::Vtables VtableFactory::getVtables(
    typelib_InterfaceTypeDescription * type)
{
    rtl::OUString name(type->aBase.pTypeName);
    osl::MutexGuard guard(m_mutex);
    Map::iterator i(m_map.find(name));
    if (i == m_map.end()) {
        GuardedBlocks blocks(*this);
        createVtables(blocks, BaseOffset(type), type, true);
        Vtables vtables;
        OSL_ASSERT(blocks.size() <= SAL_MAX_INT32);
        vtables.count = static_cast< sal_Int32 >(blocks.size());
        bridges::cpp_uno::shared::GuardedArray< Block > guardedBlocks(
            new Block[vtables.count]);
        vtables.blocks = guardedBlocks.get();
        for (sal_Int32 j = 0; j < vtables.count; ++j) {
            vtables.blocks[j] = blocks[j];
        }
        i = m_map.insert(Map::value_type(name, vtables)).first;
        guardedBlocks.release();
        blocks.unguard();
    }
    return i->second;
}

void VtableFactory::freeBlock(Block const & block) const {
    rtl_arena_free(m_arena, block.start, block.size);
}

void VtableFactory::createVtables(
    GuardedBlocks & blocks, BaseOffset const & baseOffset,
    typelib_InterfaceTypeDescription * type, bool includePrimary) const
{
    if (includePrimary) {
        sal_Int32 slotCount
            = bridges::cpp_uno::shared::getPrimaryFunctions(type);
        Block block;
        block.size = getBlockSize(slotCount);
        block.start = rtl_arena_alloc(m_arena, &block.size);
        if (block.start == 0) {
            throw std::bad_alloc();
        }
        try {
            void ** slots = initializeBlock(block.start) + slotCount;
            unsigned char * codeBegin =
                reinterpret_cast< unsigned char * >(slots);
            unsigned char * code = codeBegin;
            sal_Int32 vtableOffset = blocks.size() * sizeof (void **);
            for (typelib_InterfaceTypeDescription const * type2 = type;
                 type2 != 0; type2 = type2->pBaseTypeDescription)
            {
                sal_Int32 functionCount
                    = bridges::cpp_uno::shared::getLocalFunctions(type2);
                slots -= functionCount;
                code = addLocalFunctions(
                    slots, code, type2,
                    baseOffset.getFunctionOffset(type2->aBase.pTypeName),
                    functionCount, vtableOffset);
            }
            flushCode(codeBegin, code);
            blocks.push_back(block);
        } catch (...) {
            freeBlock(block);
            throw;
        }
    }
    for (sal_Int32 i = 0; i < type->nBaseTypes; ++i) {
        createVtables(blocks, baseOffset, type->ppBaseTypes[i], i != 0);
    }
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkCommunicator.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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

#include "vtkCommunicator.h"
#include "vtkDataSetReader.h"
#include "vtkDataSetWriter.h"
#include "vtkStructuredPointsReader.h"
#include "vtkStructuredPointsWriter.h"
#include "vtkImageClip.h"
#include "vtkCharArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"

template <class T>
static int SendDataArray(T* data, int length, int handle, int tag, vtkCommunicator *self)
{

  self->Send(data, length, handle, tag);

  return 1;
}

template <class T>
static int ReceiveDataArray(T* data, int length, int handle, int tag, vtkDataArray *array)
{
  return 1;
}

vtkCommunicator::vtkCommunicator()
{
  this->MarshalString = 0;
  this->MarshalStringLength = 0;
  this->MarshalDataLength = 0;

}

vtkCommunicator::~vtkCommunicator()
{
  this->DeleteAndSetMarshalString(0, 0);
}

void vtkCommunicator::PrintSelf(ostream& os, vtkIndent indent)
{
  os << indent << "Marshal string: ";
  if ( this->MarshalString )
    {
    os << this->MarshalString << endl;
    }
  else
    {
    os << "(None)" << endl;
    }
  os << indent << "Marshal string length: " << this->MarshalStringLength
     << endl;
  os << indent << "Marshal data length: " << this->MarshalDataLength
     << endl;
}

//----------------------------------------------------------------------------
// Internal method.  Assumes responsibility for deleting the string
void vtkCommunicator::DeleteAndSetMarshalString(char *str, int strLength)
{
  // delete any previous string
  if (this->MarshalString)
    {
    delete [] this->MarshalString;
    this->MarshalString = 0;
    this->MarshalStringLength = 0;
    this->MarshalDataLength = 0;
    }

  this->MarshalString = str;
  this->MarshalStringLength = strLength;
}

// Need to add better error checking
int vtkCommunicator::Send(vtkDataObject* data, int remoteHandle,
			  int tag)
{

  if (data == NULL)
    {
    this->MarshalDataLength = 0;
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    return 1;
    }
  if (this->WriteObject(data))
    {
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    // then send the string.

    this->Send( this->MarshalString, this->MarshalDataLength,
		remoteHandle, tag);

    return 1;
    }

  // could not marshal data
  return 0;
}

int vtkCommunicator::Send(vtkDataArray* data, int remoteHandle, int tag)
{

  if (data == NULL)
    {
    this->MarshalDataLength = 0;
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    return 1;
    }

  // send array type
  int type = data->GetDataType();
  this->Send( &type, 1, remoteHandle, tag);

  // send array size
  vtkIdType size = data->GetSize();
  this->Send( &size, 1, remoteHandle, tag);

  // send number of components in array
  int numComponents = data->GetNumberOfComponents();
  this->Send( &numComponents, 1, remoteHandle, tag);

  const char* name = data->GetName();
  int len = strlen(name) + 1;

  // send length of name
  this->Send( &len, 1, remoteHandle, tag);

  // send name
  this->Send( const_cast<char*>(name), len, remoteHandle, tag);

  // now send the raw array
  switch (type)
    {

    case VTK_CHAR:
      return SendDataArray(static_cast<char*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_UNSIGNED_CHAR:
      return SendDataArray(static_cast<unsigned char*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_INT:
      return SendDataArray(static_cast<int*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_UNSIGNED_LONG:
      return SendDataArray(static_cast<unsigned long*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_FLOAT:
      return SendDataArray(static_cast<float*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_DOUBLE:
      return SendDataArray(static_cast<double*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_ID_TYPE:
      return SendDataArray(static_cast<vtkIdType*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    default:
      vtkErrorMacro(<<"Unsupported data type!");
      return 0; // could not marshal data

    }

}

int vtkCommunicator::Receive(vtkDataObject* data, int remoteHandle,
			     int tag)
{
  int dataLength;

  // First receive the data length.
  if (!this->Receive( &dataLength, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  if (dataLength < 0)
    {
    vtkErrorMacro("Bad data length");
    return 0;
    }

  if (dataLength == 0)
    { // This indicates a NULL object was sent. Do nothing.
    return 1;
    }

  // if we cannot reuse the string, allocate a new one.
  if (dataLength > this->MarshalStringLength)
    {
    char *str = new char[dataLength + 10]; // maybe a little extra?
    this->DeleteAndSetMarshalString(str, dataLength + 10);
    }

  // Receive the string
  this->Receive(this->MarshalString, dataLength,
		remoteHandle, tag);
  this->MarshalDataLength = dataLength;

  this->ReadObject(data);

  // we should really look at status to determine success
  return 1;
}

int vtkCommunicator::Receive(vtkDataArray* data, int remoteHandle,
			     int tag)
{
  vtkIdType size;
  int type;
  int numComponents;
  int nameLength;

  char *c = 0;
  unsigned char *uc = 0;
  int *i = 0;
  unsigned long *ul = 0;
  float *f = 0;
  double *d = 0;
  vtkIdType *idt = 0;

  // First receive the data type.
  if (!this->Receive( &type, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  // Next receive the data length.
  if (!this->Receive( &size, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  // Next receive the number of components.
  this->Receive( &numComponents, 1, remoteHandle, tag);

  // Next receive the length of the name.
  this->Receive( &nameLength, 1, remoteHandle, tag);

  char *str = new char[nameLength];
  this->DeleteAndSetMarshalString(str, nameLength);

  // Receive the name
  this->Receive(this->MarshalString, nameLength, remoteHandle, tag);
  this->MarshalDataLength = nameLength;

  if (size < 0)
    {
    vtkErrorMacro("Bad data length");
    return 0;
    }

  if (size == 0)
    { // This indicates a NULL object was sent. Do nothing.
    return 1;
    }

  // Receive the raw data array
  switch (type)
    {

    case VTK_CHAR:
      c = new char[size];
      this->Receive(c, size, remoteHandle, tag);
      static_cast<vtkCharArray*>(data)->SetArray(c, size, 0);
      break;

    case VTK_UNSIGNED_CHAR:
      uc = new unsigned char[size];
      this->Receive(uc, size, remoteHandle, tag);
      static_cast<vtkUnsignedCharArray*>(data)->SetArray(uc, size, 0);
      break;

    case VTK_INT:
      i = new int[size];
      this->Receive(i, size, remoteHandle, tag);
      static_cast<vtkIntArray*>(data)->SetArray(i, size, 0);
      break;

    case VTK_UNSIGNED_LONG:
      ul = new unsigned long[size];
      this->Receive(ul, size, remoteHandle, tag);
      static_cast<vtkUnsignedLongArray*>(data)->SetArray(ul, size, 0);
      break;

    case VTK_FLOAT:
      f = new float[size];
      this->Receive(f, size, remoteHandle, tag);
      static_cast<vtkFloatArray*>(data)->SetArray(f, size, 0);
      break;

    case VTK_DOUBLE:

      d = new double[size];
      this->Receive(d, size, remoteHandle, tag);
      static_cast<vtkDoubleArray*>(data)->SetArray(d, size, 0);
      break;

    case VTK_ID_TYPE:
      idt = new vtkIdType[size];
      this->Receive(idt, size, remoteHandle, tag);
      static_cast<vtkIdTypeArray*>(data)->SetArray(idt, size, 0);
      break;

    default:
      vtkErrorMacro(<<"Unsupported data type!");
      return 0; // could not marshal data

    }

  data->SetName(this->MarshalString);
  data->SetNumberOfComponents(numComponents);

  return 1;

}

int vtkCommunicator::WriteObject(vtkDataObject *data)
{
  if (strcmp(data->GetClassName(), "vtkPolyData") == 0          ||
      strcmp(data->GetClassName(), "vtkUnstructuredGrid") == 0  ||
      strcmp(data->GetClassName(), "vtkStructuredGrid") == 0    ||
      strcmp(data->GetClassName(), "vtkRectilinearGrid") == 0   ||
      strcmp(data->GetClassName(), "vtkStructuredPoints") == 0)
    {
    return this->WriteDataSet((vtkDataSet*)data);
    }
  if (strcmp(data->GetClassName(), "vtkImageData") == 0)
    {
    return this->WriteImageData((vtkImageData*)data);
    }

  vtkErrorMacro("Cannot marshal object of type "
		<< data->GetClassName());
  return 0;
}

int vtkCommunicator::ReadObject(vtkDataObject *data)
{
  if (strcmp(data->GetClassName(), "vtkPolyData") == 0          ||
      strcmp(data->GetClassName(), "vtkUnstructuredGrid") == 0  ||
      strcmp(data->GetClassName(), "vtkStructuredGrid") == 0    ||
      strcmp(data->GetClassName(), "vtkRectilinearGrid") == 0   ||
      strcmp(data->GetClassName(), "vtkStructuredPoints") == 0)
    {
    return this->ReadDataSet((vtkDataSet*)data);
    }
  if (strcmp(data->GetClassName(), "vtkImageData") == 0)
    {
    return this->ReadImageData((vtkImageData*)data);
    }

  vtkErrorMacro("Cannot marshal object of type "
		<< data->GetClassName());

  return 1;
}

int vtkCommunicator::WriteImageData(vtkImageData *data)
{
  vtkImageClip *clip;
  vtkStructuredPointsWriter *writer;
  int size;

  // keep Update from propagating
  vtkImageData *tmp = vtkImageData::New();
  tmp->ShallowCopy(data);

  clip = vtkImageClip::New();
  clip->SetInput(tmp);
  clip->SetOutputWholeExtent(data->GetExtent());
  writer = vtkStructuredPointsWriter::New();
  writer->SetFileTypeToBinary();
  writer->WriteToOutputStringOn();
  writer->SetInput(clip->GetOutput());
  writer->Write();
  size = writer->GetOutputStringLength();

  this->DeleteAndSetMarshalString(writer->RegisterAndGetOutputString(), size);
  this->MarshalDataLength = size;
  clip->Delete();
  writer->Delete();
  tmp->Delete();

  return 1;
}

int vtkCommunicator::ReadImageData(vtkImageData *object)
{
  vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();

  if (this->MarshalString == NULL || this->MarshalStringLength <= 0)
    {
    return 0;
    }

  reader->ReadFromInputStringOn();
  reader->SetInputString(this->MarshalString, this->MarshalDataLength);
  reader->GetOutput()->Update();

  object->ShallowCopy(reader->GetOutput());

  reader->Delete();

  return 1;
}

int vtkCommunicator::WriteDataSet(vtkDataSet *data)
{
  vtkDataSet *copy;
  unsigned long size;
  vtkDataSetWriter *writer = vtkDataSetWriter::New();

  copy = (vtkDataSet*)(data->MakeObject());
  copy->ShallowCopy(data);

  // There is a problem with binary files with no data.
  if (copy->GetNumberOfCells() > 0)
    {
    writer->SetFileTypeToBinary();
    }
  writer->WriteToOutputStringOn();
  writer->SetInput(copy);

  writer->Write();
  size = writer->GetOutputStringLength();
  this->DeleteAndSetMarshalString(writer->RegisterAndGetOutputString(), size);
  this->MarshalDataLength = size;
  writer->Delete();
  copy->Delete();

  return 1;
}

int vtkCommunicator::ReadDataSet(vtkDataSet *object)
{
  vtkDataSet *output;
  vtkDataSetReader *reader = vtkDataSetReader::New();

  if (this->MarshalString == NULL || this->MarshalStringLength <= 0)
    {
    return 0;
    }

  reader->ReadFromInputStringOn();
  reader->SetInputString(this->MarshalString, this->MarshalDataLength);
  output = reader->GetOutput();
  output->Update();

  object->ShallowCopy(output);
  //object->DataHasBeenGenerated();

  reader->Delete();

  return 1;
}
<commit_msg>Array no longer always have names<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkCommunicator.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 1993-2001 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * Neither name of Ken Martin, Will Schroeder, or Bill Lorensen nor the names
   of any contributors may be used to endorse or promote products derived
   from this software without specific prior written permission.

 * Modified source versions must be plainly marked as such, and must not be
   misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

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

#include "vtkCommunicator.h"
#include "vtkDataSetReader.h"
#include "vtkDataSetWriter.h"
#include "vtkStructuredPointsReader.h"
#include "vtkStructuredPointsWriter.h"
#include "vtkImageClip.h"
#include "vtkCharArray.h"
#include "vtkUnsignedCharArray.h"
#include "vtkIntArray.h"
#include "vtkUnsignedLongArray.h"
#include "vtkFloatArray.h"
#include "vtkDoubleArray.h"
#include "vtkIdTypeArray.h"

template <class T>
static int SendDataArray(T* data, int length, int handle, int tag, vtkCommunicator *self)
{

  self->Send(data, length, handle, tag);

  return 1;
}

template <class T>
static int ReceiveDataArray(T* data, int length, int handle, int tag, vtkDataArray *array)
{
  return 1;
}

vtkCommunicator::vtkCommunicator()
{
  this->MarshalString = 0;
  this->MarshalStringLength = 0;
  this->MarshalDataLength = 0;

}

vtkCommunicator::~vtkCommunicator()
{
  this->DeleteAndSetMarshalString(0, 0);
}

void vtkCommunicator::PrintSelf(ostream& os, vtkIndent indent)
{
  os << indent << "Marshal string: ";
  if ( this->MarshalString )
    {
    os << this->MarshalString << endl;
    }
  else
    {
    os << "(None)" << endl;
    }
  os << indent << "Marshal string length: " << this->MarshalStringLength
     << endl;
  os << indent << "Marshal data length: " << this->MarshalDataLength
     << endl;
}

//----------------------------------------------------------------------------
// Internal method.  Assumes responsibility for deleting the string
void vtkCommunicator::DeleteAndSetMarshalString(char *str, int strLength)
{
  // delete any previous string
  if (this->MarshalString)
    {
    delete [] this->MarshalString;
    this->MarshalString = 0;
    this->MarshalStringLength = 0;
    this->MarshalDataLength = 0;
    }

  this->MarshalString = str;
  this->MarshalStringLength = strLength;
}

// Need to add better error checking
int vtkCommunicator::Send(vtkDataObject* data, int remoteHandle,
			  int tag)
{

  if (data == NULL)
    {
    this->MarshalDataLength = 0;
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    return 1;
    }
  if (this->WriteObject(data))
    {
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    // then send the string.

    this->Send( this->MarshalString, this->MarshalDataLength,
		remoteHandle, tag);

    return 1;
    }

  // could not marshal data
  return 0;
}

int vtkCommunicator::Send(vtkDataArray* data, int remoteHandle, int tag)
{

  if (data == NULL)
    {
    this->MarshalDataLength = 0;
    this->Send( &this->MarshalDataLength, 1,
		remoteHandle, tag);
    return 1;
    }

  // send array type
  int type = data->GetDataType();
  this->Send( &type, 1, remoteHandle, tag);

  // send array size
  vtkIdType size = data->GetSize();
  this->Send( &size, 1, remoteHandle, tag);

  // send number of components in array
  int numComponents = data->GetNumberOfComponents();
  this->Send( &numComponents, 1, remoteHandle, tag);

  const char* name = data->GetName();
  int len = 0;
  if (name)
    {
    len = strlen(name) + 1;
    }

  // send length of name
  this->Send( &len, 1, remoteHandle, tag);

  if (len > 0)
    {
    // send name
    this->Send( const_cast<char*>(name), len, remoteHandle, tag);
    }

  // now send the raw array
  switch (type)
    {

    case VTK_CHAR:
      return SendDataArray(static_cast<char*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_UNSIGNED_CHAR:
      return SendDataArray(static_cast<unsigned char*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_INT:
      return SendDataArray(static_cast<int*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_UNSIGNED_LONG:
      return SendDataArray(static_cast<unsigned long*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_FLOAT:
      return SendDataArray(static_cast<float*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_DOUBLE:
      return SendDataArray(static_cast<double*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    case VTK_ID_TYPE:
      return SendDataArray(static_cast<vtkIdType*>(data->GetVoidPointer(0)),
			  size, remoteHandle, tag, this);

    default:
      vtkErrorMacro(<<"Unsupported data type!");
      return 0; // could not marshal data

    }

}

int vtkCommunicator::Receive(vtkDataObject* data, int remoteHandle,
			     int tag)
{
  int dataLength;

  // First receive the data length.
  if (!this->Receive( &dataLength, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  if (dataLength < 0)
    {
    vtkErrorMacro("Bad data length");
    return 0;
    }

  if (dataLength == 0)
    { // This indicates a NULL object was sent. Do nothing.
    return 1;
    }

  // if we cannot reuse the string, allocate a new one.
  if (dataLength > this->MarshalStringLength)
    {
    char *str = new char[dataLength + 10]; // maybe a little extra?
    this->DeleteAndSetMarshalString(str, dataLength + 10);
    }

  // Receive the string
  this->Receive(this->MarshalString, dataLength,
		remoteHandle, tag);
  this->MarshalDataLength = dataLength;

  this->ReadObject(data);

  // we should really look at status to determine success
  return 1;
}

int vtkCommunicator::Receive(vtkDataArray* data, int remoteHandle,
			     int tag)
{
  vtkIdType size;
  int type;
  int numComponents;
  int nameLength;

  char *c = 0;
  unsigned char *uc = 0;
  int *i = 0;
  unsigned long *ul = 0;
  float *f = 0;
  double *d = 0;
  vtkIdType *idt = 0;

  // First receive the data type.
  if (!this->Receive( &type, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  // Next receive the data length.
  if (!this->Receive( &size, 1, remoteHandle, tag))
    {
    vtkErrorMacro("Could not receive data!");
    return 0;
    }

  // Next receive the number of components.
  this->Receive( &numComponents, 1, remoteHandle, tag);

  // Next receive the length of the name.
  this->Receive( &nameLength, 1, remoteHandle, tag);

  if ( nameLength > 0 )
    {
    char *str = new char[nameLength];
    this->DeleteAndSetMarshalString(str, nameLength);

    // Receive the name
    this->Receive(this->MarshalString, nameLength, remoteHandle, tag);
    this->MarshalDataLength = nameLength;
    }

  if (size < 0)
    {
    vtkErrorMacro("Bad data length");
    return 0;
    }

  if (size == 0)
    { // This indicates a NULL object was sent. Do nothing.
    return 1;
    }

  // Receive the raw data array
  switch (type)
    {

    case VTK_CHAR:
      c = new char[size];
      this->Receive(c, size, remoteHandle, tag);
      static_cast<vtkCharArray*>(data)->SetArray(c, size, 0);
      break;

    case VTK_UNSIGNED_CHAR:
      uc = new unsigned char[size];
      this->Receive(uc, size, remoteHandle, tag);
      static_cast<vtkUnsignedCharArray*>(data)->SetArray(uc, size, 0);
      break;

    case VTK_INT:
      i = new int[size];
      this->Receive(i, size, remoteHandle, tag);
      static_cast<vtkIntArray*>(data)->SetArray(i, size, 0);
      break;

    case VTK_UNSIGNED_LONG:
      ul = new unsigned long[size];
      this->Receive(ul, size, remoteHandle, tag);
      static_cast<vtkUnsignedLongArray*>(data)->SetArray(ul, size, 0);
      break;

    case VTK_FLOAT:
      f = new float[size];
      this->Receive(f, size, remoteHandle, tag);
      static_cast<vtkFloatArray*>(data)->SetArray(f, size, 0);
      break;

    case VTK_DOUBLE:

      d = new double[size];
      this->Receive(d, size, remoteHandle, tag);
      static_cast<vtkDoubleArray*>(data)->SetArray(d, size, 0);
      break;

    case VTK_ID_TYPE:
      idt = new vtkIdType[size];
      this->Receive(idt, size, remoteHandle, tag);
      static_cast<vtkIdTypeArray*>(data)->SetArray(idt, size, 0);
      break;

    default:
      vtkErrorMacro(<<"Unsupported data type!");
      return 0; // could not marshal data

    }

  if (nameLength > 0)
    {
    data->SetName(this->MarshalString);
    }
  else
    {
    data->SetName(0);
    }
  data->SetNumberOfComponents(numComponents);

  return 1;

}

int vtkCommunicator::WriteObject(vtkDataObject *data)
{
  if (strcmp(data->GetClassName(), "vtkPolyData") == 0          ||
      strcmp(data->GetClassName(), "vtkUnstructuredGrid") == 0  ||
      strcmp(data->GetClassName(), "vtkStructuredGrid") == 0    ||
      strcmp(data->GetClassName(), "vtkRectilinearGrid") == 0   ||
      strcmp(data->GetClassName(), "vtkStructuredPoints") == 0)
    {
    return this->WriteDataSet((vtkDataSet*)data);
    }
  if (strcmp(data->GetClassName(), "vtkImageData") == 0)
    {
    return this->WriteImageData((vtkImageData*)data);
    }

  vtkErrorMacro("Cannot marshal object of type "
		<< data->GetClassName());
  return 0;
}

int vtkCommunicator::ReadObject(vtkDataObject *data)
{
  if (strcmp(data->GetClassName(), "vtkPolyData") == 0          ||
      strcmp(data->GetClassName(), "vtkUnstructuredGrid") == 0  ||
      strcmp(data->GetClassName(), "vtkStructuredGrid") == 0    ||
      strcmp(data->GetClassName(), "vtkRectilinearGrid") == 0   ||
      strcmp(data->GetClassName(), "vtkStructuredPoints") == 0)
    {
    return this->ReadDataSet((vtkDataSet*)data);
    }
  if (strcmp(data->GetClassName(), "vtkImageData") == 0)
    {
    return this->ReadImageData((vtkImageData*)data);
    }

  vtkErrorMacro("Cannot marshal object of type "
		<< data->GetClassName());

  return 1;
}

int vtkCommunicator::WriteImageData(vtkImageData *data)
{
  vtkImageClip *clip;
  vtkStructuredPointsWriter *writer;
  int size;

  // keep Update from propagating
  vtkImageData *tmp = vtkImageData::New();
  tmp->ShallowCopy(data);

  clip = vtkImageClip::New();
  clip->SetInput(tmp);
  clip->SetOutputWholeExtent(data->GetExtent());
  writer = vtkStructuredPointsWriter::New();
  writer->SetFileTypeToBinary();
  writer->WriteToOutputStringOn();
  writer->SetInput(clip->GetOutput());
  writer->Write();
  size = writer->GetOutputStringLength();

  this->DeleteAndSetMarshalString(writer->RegisterAndGetOutputString(), size);
  this->MarshalDataLength = size;
  clip->Delete();
  writer->Delete();
  tmp->Delete();

  return 1;
}

int vtkCommunicator::ReadImageData(vtkImageData *object)
{
  vtkStructuredPointsReader *reader = vtkStructuredPointsReader::New();

  if (this->MarshalString == NULL || this->MarshalStringLength <= 0)
    {
    return 0;
    }

  reader->ReadFromInputStringOn();
  reader->SetInputString(this->MarshalString, this->MarshalDataLength);
  reader->GetOutput()->Update();

  object->ShallowCopy(reader->GetOutput());

  reader->Delete();

  return 1;
}

int vtkCommunicator::WriteDataSet(vtkDataSet *data)
{
  vtkDataSet *copy;
  unsigned long size;
  vtkDataSetWriter *writer = vtkDataSetWriter::New();

  copy = (vtkDataSet*)(data->MakeObject());
  copy->ShallowCopy(data);

  // There is a problem with binary files with no data.
  if (copy->GetNumberOfCells() > 0)
    {
    writer->SetFileTypeToBinary();
    }
  writer->WriteToOutputStringOn();
  writer->SetInput(copy);

  writer->Write();
  size = writer->GetOutputStringLength();
  this->DeleteAndSetMarshalString(writer->RegisterAndGetOutputString(), size);
  this->MarshalDataLength = size;
  writer->Delete();
  copy->Delete();

  return 1;
}

int vtkCommunicator::ReadDataSet(vtkDataSet *object)
{
  vtkDataSet *output;
  vtkDataSetReader *reader = vtkDataSetReader::New();

  if (this->MarshalString == NULL || this->MarshalStringLength <= 0)
    {
    return 0;
    }

  reader->ReadFromInputStringOn();
  reader->SetInputString(this->MarshalString, this->MarshalDataLength);
  output = reader->GetOutput();
  output->Update();

  object->ShallowCopy(output);
  //object->DataHasBeenGenerated();

  reader->Delete();

  return 1;
}
<|endoftext|>


<commit_before>//===--- BindingInferenceTests.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "SemaFixture.h"
#include "swift/AST/Expr.h"
#include "swift/Sema/ConstraintSystem.h"

using namespace swift;
using namespace swift::unittest;
using namespace swift::constraints;

TEST_F(SemaTest, TestIntLiteralBindingInference) {
  ConstraintSystemOptions options;
  options |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;

  ConstraintSystem cs(DC, options);

  auto *intLiteral = IntegerLiteralExpr::createFromUnsigned(Context, 42);

  auto *literalTy = cs.createTypeVariable(cs.getConstraintLocator(intLiteral),
                                          /*options=*/0);

  cs.addConstraint(
      ConstraintKind::LiteralConformsTo, literalTy,
      Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral)
          ->getDeclaredInterfaceType(),
      cs.getConstraintLocator(intLiteral));

  auto bindings = cs.inferBindingsFor(literalTy);

  ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);

  const auto &binding = bindings.Bindings.front();

  ASSERT_TRUE(binding.BindingType->isEqual(getStdlibType("Int")));
  ASSERT_TRUE(binding.hasDefaultedLiteralProtocol());
}
<commit_msg>[unittest/Sema] Add a test-case for a single hop protocol requirement inference<commit_after>//===--- BindingInferenceTests.cpp ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2020 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "SemaFixture.h"
#include "swift/AST/Expr.h"
#include "swift/Sema/ConstraintSystem.h"
#include "llvm/ADT/SmallPtrSet.h"

using namespace swift;
using namespace swift::unittest;
using namespace swift::constraints;

TEST_F(SemaTest, TestIntLiteralBindingInference) {
  ConstraintSystemOptions options;
  options |= ConstraintSystemFlags::AllowUnresolvedTypeVariables;

  ConstraintSystem cs(DC, options);

  auto *intLiteral = IntegerLiteralExpr::createFromUnsigned(Context, 42);

  auto *literalTy = cs.createTypeVariable(cs.getConstraintLocator(intLiteral),
                                          /*options=*/0);

  cs.addConstraint(
      ConstraintKind::LiteralConformsTo, literalTy,
      Context.getProtocol(KnownProtocolKind::ExpressibleByIntegerLiteral)
          ->getDeclaredInterfaceType(),
      cs.getConstraintLocator(intLiteral));

  auto bindings = cs.inferBindingsFor(literalTy);

  ASSERT_EQ(bindings.Bindings.size(), (unsigned)1);

  const auto &binding = bindings.Bindings.front();

  ASSERT_TRUE(binding.BindingType->isEqual(getStdlibType("Int")));
  ASSERT_TRUE(binding.hasDefaultedLiteralProtocol());
}

TEST_F(SemaTest, TestTransitiveProtocolInference) {
  ConstraintSystemOptions options;
  ConstraintSystem cs(DC, options);

  auto *PD1 =
      new (Context) ProtocolDecl(DC, SourceLoc(), SourceLoc(),
                                 Context.getIdentifier("P1"), /*Inherited=*/{},
                                 /*trailingWhere=*/nullptr);
  PD1->setImplicit();

  auto *protocolTy1 = ProtocolType::get(PD1, Type(), Context);

  auto *GPT = cs.createTypeVariable(cs.getConstraintLocator({}),
                                    /*options=*/TVO_CanBindToNoEscape);

  cs.addConstraint(
      ConstraintKind::ConformsTo, GPT, protocolTy1,
      cs.getConstraintLocator({}, LocatorPathElt::TypeParameterRequirement(
                                      0, RequirementKind::Conformance)));

  // First, let's try inferring through a single conversion
  // relationship.
  {
    auto *typeVar = cs.createTypeVariable(cs.getConstraintLocator({}),
                                          /*options=*/0);

    cs.addConstraint(
        ConstraintKind::Conversion, typeVar, GPT,
        cs.getConstraintLocator({}, LocatorPathElt::ContextualType()));

    auto bindings = inferBindings(cs, typeVar);
    ASSERT_TRUE(bindings.Protocols.empty());

    const auto &inferredProtocols = bindings.TransitiveProtocols;
    ASSERT_TRUE(bool(inferredProtocols));
    ASSERT_EQ(inferredProtocols->size(), (unsigned)1);
    ASSERT_TRUE(
        (*inferredProtocols->begin())->getSecondType()->isEqual(protocolTy1));
  }
}
<|endoftext|>