<commit_before>
// Copyright (c) 2014-2015 Dims dev-team
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "common/setResponseVisitor.h"
#include "common/events.h"
#include "common/authenticationProvider.h"
#include "common/requests.h"
#include "common/communicationProtocol.h"

#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include "monitor/provideInfoAction.h"
#include "monitor/monitorRequests.h"
#include "monitor/filters.h"
#include "monitor/reputationTracer.h"

namespace monitor
{

unsigned int const LoopTime = 20000;//milisec

struct CProvideInfo;
struct CAskForInfo;

struct CAskForInfoEvent : boost::statechart::event< CAskForInfoEvent >
{
};

struct CProvideInfoEvent : boost::statechart::event< CProvideInfoEvent >
{
};

struct CInit : boost::statechart::state< CInit, CProvideInfoAction >
{
	CInit( my_context ctx ) : my_base( ctx )
	{}

	typedef boost::mpl::list<
	boost::statechart::transition< CProvideInfoEvent, CProvideInfo >,
	boost::statechart::transition< CAskForInfoEvent, CAskForInfo >
	> reactions;

};

struct CProvideInfo : boost::statechart::state< CProvideInfo, CProvideInfoAction >
{
	CProvideInfo( my_context ctx ) : my_base( ctx )
	{
	}

	boost::statechart::result react( common::CAckEvent const & _promptAck )
	{
		context< CProvideInfoAction >().setExit();
		return discard_event();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CInfoRequestData requestedInfo;

		common::convertPayload( orginalMessage, requestedInfo );

		context< CProvideInfoAction >().forgetRequests();

		m_id = _messageResult.m_message.m_header.m_id;

		common::CSendMessageRequest * request =
				new common::CSendMessageRequest(
					common::CPayloadKind::Ack
					, context< CProvideInfoAction >().getActionKey()
					, _messageResult.m_message.m_header.m_id
					, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

		request->addPayload( common::CAck() );

		context< CProvideInfoAction >().addRequest( request );

		context< CProvideInfoAction >().addRequest(
					new common::CTimeEventRequest(
						  LoopTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

		if ( requestedInfo.m_kind == (int)common::CInfoKind::IsAddmited )
		{
			CPubKey pubKey;
			CReputationTracker::getInstance()->getNodeToKey( context< CProvideInfoAction >().getNodeIndicator(), pubKey );

			common::CSendMessageRequest * request =
					new common::CSendMessageRequest(
						common::CPayloadKind::Result
						, context< CProvideInfoAction >().getActionKey()
						, context< CProvideInfoAction >().getInfoRequestKey()
						, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

			request->addPayload(
						common::CResult( CReputationTracker::getInstance()->isAddmitedMonitor( pubKey ) ? 1 : 0 ) );

			context< CProvideInfoAction >().addRequest( request );

		}
		else if ( requestedInfo.m_kind == (int)common::CInfoKind::IsRegistered )
		{

			CPubKey pubKey;
			CReputationTracker::getInstance()->getNodeToKey( context< CProvideInfoAction >().getNodeIndicator(), pubKey );

			common::CTrackerData trackerData;
			CPubKey monitorPubKey;
			CReputationTracker::getInstance()->checkForTracker( pubKey, trackerData, monitorPubKey );

			common::CSendMessageRequest * request =
					new common::CSendMessageRequest(
						common::CPayloadKind::ValidRegistration
						, context< CProvideInfoAction >().getActionKey()
						, context< CProvideInfoAction >().getInfoRequestKey()
						, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

			request->addPayload(
						common::CValidRegistration(
							monitorPubKey
							, trackerData.m_contractTime
							, trackerData.m_networkTime ) );

			context< CProvideInfoAction >().addRequest( request );

		}

		return discard_event();
	}

	boost::statechart::result react( common::CAvailableCoinsData const & _availableCoins )
	{
		common::CSendMessageRequest * request =
				new common::CSendMessageRequest(
					common::CPayloadKind::Balance
					, context< CProvideInfoAction >().getActionKey()
					, m_id
					, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

		request->addPayload( common::CBalance( _availableCoins.m_availableCoins ) );

		context< CProvideInfoAction >().addRequest( request );

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CProvideInfoAction >().forgetRequests();
		context< CProvideInfoAction >().setExit();

		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CMessageResult >,
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CAvailableCoinsData >,
	boost::statechart::custom_reaction< common::CTimeEvent >
	> reactions;

	uint256 m_id;
};

struct CAskForInfo : boost::statechart::state< CAskForInfo, CProvideInfoAction >
{
	CAskForInfo( my_context ctx ) : my_base( ctx )
	{
		context< CProvideInfoAction >().addRequest( new common::CInfoAskRequest(
														  context< CProvideInfoAction >().getInfo()
														, context< CProvideInfoAction >().getActionKey()
														, new CMediumClassFilter( common::CMediumKinds::Monitors, 1 ) ) );

		context< CProvideInfoAction >().addRequest(
					new common::CTimeEventRequest(
						  LoopTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CAckEvent const & _promptAck )
	{
		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CProvideInfoAction >().forgetRequests();
		context< CProvideInfoAction >().setExit();

		return discard_event();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{

		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		context< CProvideInfoAction >().addRequest(
					new common::CAckRequest(
						  context< CProvideInfoAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( _messageResult.m_nodeIndicator ) ) );

		if ( ( common::CPayloadKind::Enum )orginalMessage.m_header.m_payloadKind == common::CPayloadKind::Result )
		{
			common::CResult result;

			common::convertPayload( orginalMessage, result );

			context< CProvideInfoAction >().setResult( result );
		}
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >,
	boost::statechart::custom_reaction< common::CAckEvent >
	> reactions;
};

struct CMonitorStop : boost::statechart::state< CMonitorStop, CProvideInfoAction >
{
	CMonitorStop( my_context ctx ) : my_base( ctx )
	{
	}
};

CProvideInfoAction::CProvideInfoAction( uint256 const & _id, uint256 const & _actionKey, uintptr_t _nodeIndicator )
	: common::CScheduleAbleAction( _actionKey )
	, m_infoRequestKey( _id )
	, m_nodeIndicator( _nodeIndicator )
{
	initiate();
}

CProvideInfoAction::CProvideInfoAction( common::CInfoKind::Enum _infoKind )
	: m_infoKind( _infoKind )
{
	initiate();
}

void
CProvideInfoAction::accept( common::CSetResponseVisitor & _visitor )
{
	_visitor.visit( *this );
}

uintptr_t
CProvideInfoAction::getNodeIndicator() const
{
	return m_nodeIndicator;
}

}

<commit_msg>small fix<commit_after>
// Copyright (c) 2014-2015 Dims dev-team
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "common/setResponseVisitor.h"
#include "common/events.h"
#include "common/authenticationProvider.h"
#include "common/requests.h"
#include "common/communicationProtocol.h"

#include <boost/statechart/simple_state.hpp>
#include <boost/statechart/state.hpp>
#include <boost/statechart/transition.hpp>
#include <boost/statechart/custom_reaction.hpp>

#include "monitor/provideInfoAction.h"
#include "monitor/monitorRequests.h"
#include "monitor/filters.h"
#include "monitor/reputationTracer.h"

namespace monitor
{

unsigned int const LoopTime = 20000;//milisec

struct CProvideInfo;
struct CAskForInfo;

struct CAskForInfoEvent : boost::statechart::event< CAskForInfoEvent >
{
};

struct CProvideInfoEvent : boost::statechart::event< CProvideInfoEvent >
{
};

struct CInit : boost::statechart::state< CInit, CProvideInfoAction >
{
	CInit( my_context ctx ) : my_base( ctx )
	{}

	typedef boost::mpl::list<
	boost::statechart::transition< CProvideInfoEvent, CProvideInfo >,
	boost::statechart::transition< CAskForInfoEvent, CAskForInfo >
	> reactions;

};

struct CProvideInfo : boost::statechart::state< CProvideInfo, CProvideInfoAction >
{
	CProvideInfo( my_context ctx ) : my_base( ctx )
	{
	}

	boost::statechart::result react( common::CAckEvent const & _promptAck )
	{
		context< CProvideInfoAction >().setExit();
		return discard_event();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{
		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		common::CInfoRequestData requestedInfo;

		common::convertPayload( orginalMessage, requestedInfo );

		context< CProvideInfoAction >().forgetRequests();

		m_id = _messageResult.m_message.m_header.m_id;

		common::CSendMessageRequest * request =
				new common::CSendMessageRequest(
					common::CPayloadKind::Ack
					, context< CProvideInfoAction >().getActionKey()
					, _messageResult.m_message.m_header.m_id
					, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

		request->addPayload( common::CAck() );

		context< CProvideInfoAction >().addRequest( request );

		context< CProvideInfoAction >().addRequest(
					new common::CTimeEventRequest(
						  LoopTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );

		if ( requestedInfo.m_kind == (int)common::CInfoKind::IsAddmited )
		{
			CPubKey pubKey;
			CReputationTracker::getInstance()->getNodeToKey( context< CProvideInfoAction >().getNodeIndicator(), pubKey );

			common::CSendMessageRequest * request =
					new common::CSendMessageRequest(
						common::CPayloadKind::Result
						, context< CProvideInfoAction >().getActionKey()
						, context< CProvideInfoAction >().getInfoRequestKey()
						, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

			request->addPayload(
						common::CResult( CReputationTracker::getInstance()->isAddmitedMonitor( pubKey ) ? 1 : 0 ) );

			context< CProvideInfoAction >().addRequest( request );

		}
		else if ( requestedInfo.m_kind == (int)common::CInfoKind::IsRegistered )
		{

			CPubKey pubKey;
			CReputationTracker::getInstance()->getNodeToKey( context< CProvideInfoAction >().getNodeIndicator(), pubKey );

			common::CTrackerData trackerData;
			CPubKey monitorPubKey;
			CReputationTracker::getInstance()->checkForTracker( pubKey, trackerData, monitorPubKey );

			common::CSendMessageRequest * request =
					new common::CSendMessageRequest(
						common::CPayloadKind::ValidRegistration
						, context< CProvideInfoAction >().getActionKey()
						, context< CProvideInfoAction >().getInfoRequestKey()
						, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

			request->addPayload(
						common::CValidRegistration(
							monitorPubKey
							, trackerData.m_contractTime
							, trackerData.m_networkTime ) );

			context< CProvideInfoAction >().addRequest( request );

		}

		return discard_event();
	}

	boost::statechart::result react( common::CAvailableCoinsData const & _availableCoins )
	{
		common::CSendMessageRequest * request =
				new common::CSendMessageRequest(
					common::CPayloadKind::Balance
					, context< CProvideInfoAction >().getActionKey()
					, m_id
					, new CSpecificMediumFilter( context< CProvideInfoAction >().getNodeIndicator() ) );

		request->addPayload( common::CBalance( _availableCoins.m_availableCoins ) );

		context< CProvideInfoAction >().addRequest( request );

		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CProvideInfoAction >().forgetRequests();
		context< CProvideInfoAction >().setExit();

		return discard_event();
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CMessageResult >,
	boost::statechart::custom_reaction< common::CAckEvent >,
	boost::statechart::custom_reaction< common::CAvailableCoinsData >,
	boost::statechart::custom_reaction< common::CTimeEvent >
	> reactions;

	uint256 m_id;
};

struct CAskForInfo : boost::statechart::state< CAskForInfo, CProvideInfoAction >
{
	CAskForInfo( my_context ctx ) : my_base( ctx )
	{
		context< CProvideInfoAction >().addRequest( new common::CInfoAskRequest(
														  context< CProvideInfoAction >().getInfo()
														, context< CProvideInfoAction >().getActionKey()
														, new CMediumClassFilter( common::CMediumKinds::Monitors, 1 ) ) );

		context< CProvideInfoAction >().addRequest(
					new common::CTimeEventRequest(
						  LoopTime
						, new CMediumClassFilter( common::CMediumKinds::Time ) ) );
	}

	boost::statechart::result react( common::CAckEvent const & _promptAck )
	{
		return discard_event();
	}

	boost::statechart::result react( common::CTimeEvent const & _timeEvent )
	{
		context< CProvideInfoAction >().forgetRequests();
		context< CProvideInfoAction >().setExit();

		return discard_event();
	}

	boost::statechart::result react( common::CMessageResult const & _messageResult )
	{

		common::CMessage orginalMessage;
		if ( !common::CommunicationProtocol::unwindMessage( _messageResult.m_message, orginalMessage, GetTime(), _messageResult.m_pubKey ) )
			assert( !"service it somehow" );

		context< CProvideInfoAction >().addRequest(
					new common::CAckRequest(
						  context< CProvideInfoAction >().getActionKey()
						, _messageResult.m_message.m_header.m_id
						, new CSpecificMediumFilter( _messageResult.m_nodeIndicator ) ) );

		if ( ( common::CPayloadKind::Enum )orginalMessage.m_header.m_payloadKind == common::CPayloadKind::Result )
		{
			common::CResult result;

			common::convertPayload( orginalMessage, result );

			context< CProvideInfoAction >().setResult( result );
		}
	}

	typedef boost::mpl::list<
	boost::statechart::custom_reaction< common::CTimeEvent >,
	boost::statechart::custom_reaction< common::CMessageResult >,
	boost::statechart::custom_reaction< common::CAckEvent >
	> reactions;
};

struct CMonitorStop : boost::statechart::state< CMonitorStop, CProvideInfoAction >
{
	CMonitorStop( my_context ctx ) : my_base( ctx )
	{
	}
};

CProvideInfoAction::CProvideInfoAction( uint256 const & _id, uint256 const & _actionKey, uintptr_t _nodeIndicator )
	: common::CScheduleAbleAction( _actionKey )
	, m_infoRequestKey( _id )
	, m_nodeIndicator( _nodeIndicator )
{
	initiate();
	process_event( CProvideInfoEvent() );
}

CProvideInfoAction::CProvideInfoAction( common::CInfoKind::Enum _infoKind )
	: m_infoKind( _infoKind )
{
	initiate();
	process_event( CAskForInfoEvent() );
}

void
CProvideInfoAction::accept( common::CSetResponseVisitor & _visitor )
{
	_visitor.visit( *this );
}

uintptr_t
CProvideInfoAction::getNodeIndicator() const
{
	return m_nodeIndicator;
}

}

<|endoftext|>


<commit_before>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2017 ScyllaDB
 */

#include "util/alloc_failure_injector.hh"

namespace seastar {
namespace memory {

thread_local alloc_failure_injector the_alloc_failure_injector;

void alloc_failure_injector::fail() {
    _failed = true;
    cancel();
    _on_alloc_failure();
}

}
}
<commit_msg>alloc_failure_injector: Log backtrace of failures<commit_after>/*
 * This file is open source software, licensed to you under the terms
 * of the Apache License, Version 2.0 (the "License").  See the NOTICE file
 * distributed with this work for additional information regarding copyright
 * ownership.  You may not use this file except in compliance with the License.
 *
 * You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
/*
 * Copyright 2017 ScyllaDB
 */

#include "util/alloc_failure_injector.hh"
#include "util/backtrace.hh"
#include "util/log.hh"

namespace seastar {
namespace memory {

static logger log("failure_injector");

thread_local alloc_failure_injector the_alloc_failure_injector;

void alloc_failure_injector::fail() {
    _failed = true;
    cancel();
    if (log.is_enabled(log_level::trace)) {
        log.trace("Failing at {}", current_backtrace());
    }
    _on_alloc_failure();
}

}
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qmediarecorder.h>

#include <qmediarecordercontrol.h>
#include <qmediaobject_p.h>
#include <qmediaservice.h>
#include <qmediaserviceprovider.h>
#include <qaudioencodercontrol.h>
#include <qvideoencodercontrol.h>
#include <qmediaformatcontrol.h>

#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>

#include <QtMultimedia/QAudioFormat>

QTM_BEGIN_NAMESPACE

/*!
    \class QMediaRecorder
    \ingroup multimedia

    \preliminary
    \brief The QMediaRecorder class is used for the recording of media content.

    The QMediaRecorder class is a high level media recording class.
    It's not intended to be used alone but for accessing the media
    recording functions of other media objects, like QRadioTuner,
    or QAudioCaptureSource.

    If the radio is used as a source, recording
    is only possible when the source is in appropriate state

    \code
    // Audio only recording
    audioSource = new QAudioCaptureSource;
    recorder = new QMediaRecorder(audioSource);

    QAudioEncoderSettings audioSettings;
    audioSettings.setCodec("audio/vorbis");
    audioSettings.setQuality(QtMedia::HighQuality);

    recorder->setEncodingSettings(audioSettings);

    recorder->setOutputLocation(QUrl::fromLocalFile(fileName));
    recorder->record();
    \endcode

    \sa
*/

class QMediaRecorderPrivate : public QMediaObjectPrivate
{
    Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)

public:
    QMediaRecorderPrivate();
    void initControls();

    QMediaRecorderControl *control;
    QMediaFormatControl *formatControl;
    QAudioEncoderControl *audioControl;
    QVideoEncoderControl *videoControl;

    QMediaRecorder::State state;
    QMediaRecorder::Error error;
    QString errorString;

    void _q_stateChanged(QMediaRecorder::State state);
    void _q_error(int error, const QString &errorString);
};

QMediaRecorderPrivate::QMediaRecorderPrivate():
     control(0),
     formatControl(0),
     audioControl(0),
     videoControl(0),
     state(QMediaRecorder::StoppedState),
     error(QMediaRecorder::NoError)
{
}

void QMediaRecorderPrivate::initControls()
{
    Q_Q(QMediaRecorder);

    if (!service)
        return;

    control = qobject_cast<QMediaRecorderControl*>(service->control(QMediaRecorderControl_iid));
    formatControl = qobject_cast<QMediaFormatControl *>(service->control(QMediaFormatControl_iid));
    audioControl = qobject_cast<QAudioEncoderControl *>(service->control(QAudioEncoderControl_iid));
    videoControl = qobject_cast<QVideoEncoderControl *>(service->control(QVideoEncoderControl_iid));

    if (control) {
        q->connect(control, SIGNAL(stateChanged(QMediaRecorder::State)),
                q, SLOT(_q_stateChanged(QMediaRecorder::State)));

        q->connect(control, SIGNAL(error(int,QString)),
                q, SLOT(_q_error(int,QString)));
    }
}

#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))

void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
{
    Q_Q(QMediaRecorder);

    if (ps == QMediaRecorder::RecordingState)
        q->addPropertyWatch("duration");
    else
        q->removePropertyWatch("duration");

//    qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
    if (state != ps) {
        emit q->stateChanged(ps);
    }

    state = ps;
}

void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
{
    Q_Q(QMediaRecorder);

    this->error = QMediaRecorder::Error(error);
    this->errorString = errorString;

    emit q->error(this->error);
}

/*!
    Constructs a media recorder which records the media produced by \a mediaObject.

    The \a parent is passed to QMediaObject.
*/

QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
    QMediaObject(*new QMediaRecorderPrivate, parent, mediaObject->service())
{
    Q_D(QMediaRecorder);

    d->initControls();
}

/*!
    Destroys a media recorder object.
*/

QMediaRecorder::~QMediaRecorder()
{
}

/*!
    \property QMediaRecorder::outputLocation
    \brief the destination location of media content.

    Setting the location can fail for example when the service supports
    only local file system locations while the network url was passed,
    or the service doesn't support media recording.
*/

QUrl QMediaRecorder::outputLocation() const
{
    return d_func()->control ? d_func()->control->outputLocation() : QUrl();
}

bool QMediaRecorder::setOutputLocation(const QUrl &location)
{
    Q_D(QMediaRecorder);
    return d->control ? d->control->setOutputLocation(location) : false;
}

/*!
    Return the current media recorder state.

    \sa QMediaRecorder::State
*/

QMediaRecorder::State QMediaRecorder::state() const
{
    return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
}

/*!
    Returns the current error state.

    \sa errorString()
*/

QMediaRecorder::Error QMediaRecorder::error() const
{
    return d_func()->error;
}

/*!
    Returns a string describing the current error state.

    \sa error()
*/

QString QMediaRecorder::errorString() const
{
    return d_func()->errorString;
}

/*!
    \property QMediaRecorder::duration

    \brief the recorded media duration in milliseconds.
*/

qint64 QMediaRecorder::duration() const
{
    return d_func()->control ? d_func()->control->duration() : 0;
}

/*!
    Returns a list of MIME types of supported container formats.
*/
QStringList QMediaRecorder::supportedFormats() const
{
    return d_func()->formatControl ?
           d_func()->formatControl->supportedFormats() : QStringList();
}

/*!
    Returns a description of a container format \a mimeType.
*/
QString QMediaRecorder::formatDescription(const QString &mimeType) const
{
    return d_func()->formatControl ?
           d_func()->formatControl->formatDescription(mimeType) : QString();
}

/*!
    Returns the MIME type of the selected container format.
*/

QString QMediaRecorder::format() const
{
    return d_func()->formatControl ?
           d_func()->formatControl->format() : QString();
}

/*!
    Returns a list of supported audio codecs.
*/
QStringList QMediaRecorder::supportedAudioCodecs() const
{
    return d_func()->audioControl ?
           d_func()->audioControl->supportedAudioCodecs() : QStringList();
}

/*!
    Returns a description of an audio \a codec.
*/
QString QMediaRecorder::audioCodecDescription(const QString &codec) const
{
    return d_func()->audioControl ?
           d_func()->audioControl->codecDescription(codec) : QString();
}

/*!
    Returns a list of supported audio sample rates.

    If non null audio \a settings parameter is passed,
    the returned list is reduced to sample rates supported with partial settings applied.

    It can be used for example to query the list of sample rates, supported by specific audio codec.

    If the encoder supports arbitrary sample rates within the supported rates range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.
*/

QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->audioControl ?
           d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>();
}

/*!
    Returns a list of resolutions video can be encoded at.  An empty list is returned if the video
    encoder supports arbitrary resolutions within the minimum and maximum range.

    If non null video \a settings parameter is passed,
    the returned list is reduced to resolution supported with partial settings like video codec or framerate applied.

    If the encoder supports arbitrary resolutions within the supported range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.

    \sa QVideoEncoderSettings::resolution()
*/
QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->videoControl ?
           d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>();
}

/*!
    Returns a list of frame rates video can be encoded at.

    If non null video \a settings parameter is passed,
    the returned list is reduced to frame rates supported with partial settings like video codec or resolution applied.

    If the encoder supports arbitrary frame rates within the supported range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.

    \sa QVideoEncoderSettings::frameRate()
*/
QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->videoControl ?
           d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>();
}

/*!
    Returns a list of supported video codecs.
*/
QStringList QMediaRecorder::supportedVideoCodecs() const
{
    return d_func()->videoControl ?
           d_func()->videoControl->supportedVideoCodecs() : QStringList();
}

/*!
    Returns a description of a video \a codec.

    \sa setEncodingSettings()
*/
QString QMediaRecorder::videoCodecDescription(const QString &codec) const
{
    return d_func()->videoControl ?
           d_func()->videoControl->videoCodecDescription(codec) : QString();
}

/*!
    Returns the audio encoder settings being used.

    \sa setEncodingSettings()
*/

QAudioEncoderSettings QMediaRecorder::audioSettings() const
{
    return d_func()->audioControl ?
           d_func()->audioControl->audioSettings() : QAudioEncoderSettings();
}

/*!
    Returns the video encoder settings being used.

    \sa setEncodingSettings()
*/

QVideoEncoderSettings QMediaRecorder::videoSettings() const
{
    return d_func()->videoControl ?
           d_func()->videoControl->videoSettings() : QVideoEncoderSettings();
}

/*!
    Sets the \a audio and \a video encoder settings and container \a format MIME type.

    It's only possible to change setttings when the encoder
    is in the QMediaEncoder::StoppedState state.

    If some parameters are not specified, or null settings are passed,
    the encoder choose the default encoding parameters, depending on
    media source properties.
    But while setEncodingSettings is optional, the backend can preload
    encoding pipeline to improve recording startup time.

    \sa audioSettings(), videoSettings(), format()
*/

void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
                                         const QVideoEncoderSettings &video,
                                         const QString &format)
{
    Q_D(QMediaRecorder);

    if (d->audioControl)
        d->audioControl->setAudioSettings(audio);

    if (d->videoControl)
        d->videoControl->setVideoSettings(video);

    if (d->formatControl)
        d->formatControl->setFormat(format);

    if (d->control)
        d->control->applySettings();
}

/*!
    Start recording.

    This is an asynchronous call, with signal
    stateCahnged(QMediaRecorder::RecordingState) being emited
    when recording started, otherwise error() signal is emited.
*/

void QMediaRecorder::record()
{
    Q_D(QMediaRecorder);

    // reset error
    d->error = NoError;
    d->errorString = QString();

    if (d->control)
        d->control->record();
}

/*!
    Pause recording.
*/

void QMediaRecorder::pause()
{
    Q_D(QMediaRecorder);
    if (d->control)
        d->control->pause();
}

/*!
    Stop recording.
*/

void QMediaRecorder::stop()
{
    Q_D(QMediaRecorder);
    if (d->control)
        d->control->stop();
}

/*!
    \enum QMediaRecorder::State

    \value StoppedState    The recorder is not active.
    \value RecordingState  The recorder is currently active and producing data.
    \value PausedState     The recorder is paused.
*/

/*!
    \enum QMediaRecorder::Error

    \value NoError         No Errors.
    \value ResourceError   Device is not ready or not available.
    \value FormatError     Current format is not supported.
*/

/*!
    \fn QMediaRecorder::stateChanged(State state)

    Signals that a media recorder's \a state has changed.
*/

/*!
    \fn QMediaRecorder::durationChanged(qint64 duration)

    Signals that the \a duration of the recorded media has changed.
*/

/*!
    \fn QMediaRecorder::error(QMediaRecorder::Error error)

    Signals that an \a error has occurred.
*/

#include "moc_qmediarecorder.cpp"
QTM_END_NAMESPACE

<commit_msg>Documentation fix.<commit_after>/****************************************************************************
**
** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** 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.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include <qmediarecorder.h>

#include <qmediarecordercontrol.h>
#include <qmediaobject_p.h>
#include <qmediaservice.h>
#include <qmediaserviceprovider.h>
#include <qaudioencodercontrol.h>
#include <qvideoencodercontrol.h>
#include <qmediaformatcontrol.h>

#include <QtCore/qdebug.h>
#include <QtCore/qurl.h>
#include <QtCore/qstringlist.h>
#include <QtCore/qmetaobject.h>

#include <QtMultimedia/QAudioFormat>

QTM_BEGIN_NAMESPACE

/*!
    \class QMediaRecorder
    \ingroup multimedia

    \preliminary
    \brief The QMediaRecorder class is used for the recording of media content.

    The QMediaRecorder class is a high level media recording class.
    It's not intended to be used alone but for accessing the media
    recording functions of other media objects, like QRadioTuner,
    or QAudioCaptureSource.

    If the radio is used as a source, recording
    is only possible when the source is in appropriate state

    \code
    // Audio only recording
    audioSource = new QAudioCaptureSource;
    recorder = new QMediaRecorder(audioSource);

    QAudioEncoderSettings audioSettings;
    audioSettings.setCodec("audio/vorbis");
    audioSettings.setQuality(QtMedia::HighQuality);

    recorder->setEncodingSettings(audioSettings);

    recorder->setOutputLocation(QUrl::fromLocalFile(fileName));
    recorder->record();
    \endcode

    \sa
*/

class QMediaRecorderPrivate : public QMediaObjectPrivate
{
    Q_DECLARE_NON_CONST_PUBLIC(QMediaRecorder)

public:
    QMediaRecorderPrivate();
    void initControls();

    QMediaRecorderControl *control;
    QMediaFormatControl *formatControl;
    QAudioEncoderControl *audioControl;
    QVideoEncoderControl *videoControl;

    QMediaRecorder::State state;
    QMediaRecorder::Error error;
    QString errorString;

    void _q_stateChanged(QMediaRecorder::State state);
    void _q_error(int error, const QString &errorString);
};

QMediaRecorderPrivate::QMediaRecorderPrivate():
     control(0),
     formatControl(0),
     audioControl(0),
     videoControl(0),
     state(QMediaRecorder::StoppedState),
     error(QMediaRecorder::NoError)
{
}

void QMediaRecorderPrivate::initControls()
{
    Q_Q(QMediaRecorder);

    if (!service)
        return;

    control = qobject_cast<QMediaRecorderControl*>(service->control(QMediaRecorderControl_iid));
    formatControl = qobject_cast<QMediaFormatControl *>(service->control(QMediaFormatControl_iid));
    audioControl = qobject_cast<QAudioEncoderControl *>(service->control(QAudioEncoderControl_iid));
    videoControl = qobject_cast<QVideoEncoderControl *>(service->control(QVideoEncoderControl_iid));

    if (control) {
        q->connect(control, SIGNAL(stateChanged(QMediaRecorder::State)),
                q, SLOT(_q_stateChanged(QMediaRecorder::State)));

        q->connect(control, SIGNAL(error(int,QString)),
                q, SLOT(_q_error(int,QString)));
    }
}

#define ENUM_NAME(c,e,v) (c::staticMetaObject.enumerator(c::staticMetaObject.indexOfEnumerator(e)).valueToKey((v)))

void QMediaRecorderPrivate::_q_stateChanged(QMediaRecorder::State ps)
{
    Q_Q(QMediaRecorder);

    if (ps == QMediaRecorder::RecordingState)
        q->addPropertyWatch("duration");
    else
        q->removePropertyWatch("duration");

//    qDebug() << "Recorder state changed:" << ENUM_NAME(QMediaRecorder,"State",ps);
    if (state != ps) {
        emit q->stateChanged(ps);
    }

    state = ps;
}

void QMediaRecorderPrivate::_q_error(int error, const QString &errorString)
{
    Q_Q(QMediaRecorder);

    this->error = QMediaRecorder::Error(error);
    this->errorString = errorString;

    emit q->error(this->error);
}

/*!
    Constructs a media recorder which records the media produced by \a mediaObject.

    The \a parent is passed to QMediaObject.
*/

QMediaRecorder::QMediaRecorder(QMediaObject *mediaObject, QObject *parent):
    QMediaObject(*new QMediaRecorderPrivate, parent, mediaObject->service())
{
    Q_D(QMediaRecorder);

    d->initControls();
}

/*!
    Destroys a media recorder object.
*/

QMediaRecorder::~QMediaRecorder()
{
}

/*!
    \property QMediaRecorder::outputLocation
    \brief the destination location of media content.

    Setting the location can fail for example when the service supports
    only local file system locations while the network url was passed,
    or the service doesn't support media recording.
*/

QUrl QMediaRecorder::outputLocation() const
{
    return d_func()->control ? d_func()->control->outputLocation() : QUrl();
}

bool QMediaRecorder::setOutputLocation(const QUrl &location)
{
    Q_D(QMediaRecorder);
    return d->control ? d->control->setOutputLocation(location) : false;
}

/*!
    Return the current media recorder state.

    \sa QMediaRecorder::State
*/

QMediaRecorder::State QMediaRecorder::state() const
{
    return d_func()->control ? QMediaRecorder::State(d_func()->control->state()) : StoppedState;
}

/*!
    Returns the current error state.

    \sa errorString()
*/

QMediaRecorder::Error QMediaRecorder::error() const
{
    return d_func()->error;
}

/*!
    Returns a string describing the current error state.

    \sa error()
*/

QString QMediaRecorder::errorString() const
{
    return d_func()->errorString;
}

/*!
    \property QMediaRecorder::duration

    \brief the recorded media duration in milliseconds.
*/

qint64 QMediaRecorder::duration() const
{
    return d_func()->control ? d_func()->control->duration() : 0;
}

/*!
    Returns a list of MIME types of supported container formats.
*/
QStringList QMediaRecorder::supportedFormats() const
{
    return d_func()->formatControl ?
           d_func()->formatControl->supportedFormats() : QStringList();
}

/*!
    Returns a description of a container format \a mimeType.
*/
QString QMediaRecorder::formatDescription(const QString &mimeType) const
{
    return d_func()->formatControl ?
           d_func()->formatControl->formatDescription(mimeType) : QString();
}

/*!
    Returns the MIME type of the selected container format.
*/

QString QMediaRecorder::format() const
{
    return d_func()->formatControl ?
           d_func()->formatControl->format() : QString();
}

/*!
    Returns a list of supported audio codecs.
*/
QStringList QMediaRecorder::supportedAudioCodecs() const
{
    return d_func()->audioControl ?
           d_func()->audioControl->supportedAudioCodecs() : QStringList();
}

/*!
    Returns a description of an audio \a codec.
*/
QString QMediaRecorder::audioCodecDescription(const QString &codec) const
{
    return d_func()->audioControl ?
           d_func()->audioControl->codecDescription(codec) : QString();
}

/*!
    Returns a list of supported audio sample rates.

    If non null audio \a settings parameter is passed,
    the returned list is reduced to sample rates supported with partial settings applied.

    It can be used for example to query the list of sample rates, supported by specific audio codec.

    If the encoder supports arbitrary sample rates within the supported rates range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.
*/

QList<int> QMediaRecorder::supportedAudioSampleRates(const QAudioEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->audioControl ?
           d_func()->audioControl->supportedSampleRates(settings, continuous) : QList<int>();
}

/*!
    Returns a list of resolutions video can be encoded at.

    If non null video \a settings parameter is passed,
    the returned list is reduced to resolution supported with partial settings like video codec or framerate applied.

    If the encoder supports arbitrary resolutions within the supported range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.

    \sa QVideoEncoderSettings::resolution()
*/
QList<QSize> QMediaRecorder::supportedResolutions(const QVideoEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->videoControl ?
           d_func()->videoControl->supportedResolutions(settings, continuous) : QList<QSize>();
}

/*!
    Returns a list of frame rates video can be encoded at.

    If non null video \a settings parameter is passed,
    the returned list is reduced to frame rates supported with partial settings like video codec or resolution applied.

    If the encoder supports arbitrary frame rates within the supported range,
    *\a continuous is set to true, otherwise *\a continuous is set to false.

    \sa QVideoEncoderSettings::frameRate()
*/
QList<qreal> QMediaRecorder::supportedFrameRates(const QVideoEncoderSettings &settings, bool *continuous) const
{
    if (continuous)
        *continuous = false;

    return d_func()->videoControl ?
           d_func()->videoControl->supportedFrameRates(settings, continuous) : QList<qreal>();
}

/*!
    Returns a list of supported video codecs.
*/
QStringList QMediaRecorder::supportedVideoCodecs() const
{
    return d_func()->videoControl ?
           d_func()->videoControl->supportedVideoCodecs() : QStringList();
}

/*!
    Returns a description of a video \a codec.

    \sa setEncodingSettings()
*/
QString QMediaRecorder::videoCodecDescription(const QString &codec) const
{
    return d_func()->videoControl ?
           d_func()->videoControl->videoCodecDescription(codec) : QString();
}

/*!
    Returns the audio encoder settings being used.

    \sa setEncodingSettings()
*/

QAudioEncoderSettings QMediaRecorder::audioSettings() const
{
    return d_func()->audioControl ?
           d_func()->audioControl->audioSettings() : QAudioEncoderSettings();
}

/*!
    Returns the video encoder settings being used.

    \sa setEncodingSettings()
*/

QVideoEncoderSettings QMediaRecorder::videoSettings() const
{
    return d_func()->videoControl ?
           d_func()->videoControl->videoSettings() : QVideoEncoderSettings();
}

/*!
    Sets the \a audio and \a video encoder settings and container \a format MIME type.

    It's only possible to change setttings when the encoder
    is in the QMediaEncoder::StoppedState state.

    If some parameters are not specified, or null settings are passed,
    the encoder choose the default encoding parameters, depending on
    media source properties.
    But while setEncodingSettings is optional, the backend can preload
    encoding pipeline to improve recording startup time.

    \sa audioSettings(), videoSettings(), format()
*/

void QMediaRecorder::setEncodingSettings(const QAudioEncoderSettings &audio,
                                         const QVideoEncoderSettings &video,
                                         const QString &format)
{
    Q_D(QMediaRecorder);

    if (d->audioControl)
        d->audioControl->setAudioSettings(audio);

    if (d->videoControl)
        d->videoControl->setVideoSettings(video);

    if (d->formatControl)
        d->formatControl->setFormat(format);

    if (d->control)
        d->control->applySettings();
}

/*!
    Start recording.

    This is an asynchronous call, with signal
    stateCahnged(QMediaRecorder::RecordingState) being emited
    when recording started, otherwise error() signal is emited.
*/

void QMediaRecorder::record()
{
    Q_D(QMediaRecorder);

    // reset error
    d->error = NoError;
    d->errorString = QString();

    if (d->control)
        d->control->record();
}

/*!
    Pause recording.
*/

void QMediaRecorder::pause()
{
    Q_D(QMediaRecorder);
    if (d->control)
        d->control->pause();
}

/*!
    Stop recording.
*/

void QMediaRecorder::stop()
{
    Q_D(QMediaRecorder);
    if (d->control)
        d->control->stop();
}

/*!
    \enum QMediaRecorder::State

    \value StoppedState    The recorder is not active.
    \value RecordingState  The recorder is currently active and producing data.
    \value PausedState     The recorder is paused.
*/

/*!
    \enum QMediaRecorder::Error

    \value NoError         No Errors.
    \value ResourceError   Device is not ready or not available.
    \value FormatError     Current format is not supported.
*/

/*!
    \fn QMediaRecorder::stateChanged(State state)

    Signals that a media recorder's \a state has changed.
*/

/*!
    \fn QMediaRecorder::durationChanged(qint64 duration)

    Signals that the \a duration of the recorded media has changed.
*/

/*!
    \fn QMediaRecorder::error(QMediaRecorder::Error error)

    Signals that an \a error has occurred.
*/

#include "moc_qmediarecorder.cpp"
QTM_END_NAMESPACE

<|endoftext|>


<commit_before>#include "hdfs_file.h"
#include "hdfs_utils.h"

using namespace std;

PyObject* FileClass_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    FileInfo *self;

    self = (FileInfo *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->fs = NULL;
        self->file = NULL;
        self->flags = 0;
        self->buff_size = 0;
        self->replication = 1;
        self->blocksize = 0;
        self->readline_chunk_size = 16 * 1024; // 16 KB
#ifdef HADOOP_LIBHDFS_V1
        self->stream_type = 0;
#endif
    }
    return (PyObject *)self;
}

#ifdef HADOOP_LIBHDFS_V1

bool hdfsFileIsOpenForWrite(FileInfo *f){
    return f->stream_type == OUTPUT;
}

bool hdfsFileIsOpenForRead(FileInfo *f){
    return f->stream_type == INPUT;
}

#endif

void FileClass_dealloc(FileInfo* self)
{
    self->file = NULL;
    self->ob_type->tp_free((PyObject*)self);
}

int FileClass_init(FileInfo *self, PyObject *args, PyObject *kwds)
{
    if (! PyArg_ParseTuple(args, "OO", &(self->fs), &(self->file))) {
        return -1;
    }

    return 0;
}

int FileClass_init_internal(FileInfo *self, hdfsFS fs, hdfsFile file)
{
    self->fs = fs;
    self->file = file;

    return 0;
}

PyObject* FileClass_close(FileInfo* self){
    int result = hdfsCloseFile(self->fs, self->file);
    if (result < 0) {
        return PyErr_SetFromErrno(PyExc_IOError);
    }
    else
        return PyBool_FromLong(1);
}

PyObject* FileClass_mode(FileInfo* self){
    return FileClass_get_mode(self);
}

PyObject* FileClass_get_mode(FileInfo *self){
    return PyLong_FromLong(self->flags);
}

PyObject* FileClass_available(FileInfo *self){
    int available = hdfsAvailable(self->fs, self->file);
    if (available < 0)
        return PyErr_SetFromErrno(PyExc_IOError);
    else
        return PyLong_FromLong(available);
}

static int _ensure_open_for_reading(FileInfo* self) {
    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForRead(self)){
    #else
    if(!hdfsFileIsOpenForRead(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in READ ('r') mode");
        return 0; // False
    }

    return 1; // True
}

static Py_ssize_t _read_into_str(FileInfo *self, char* buf, Py_ssize_t nbytes) {

    if (nbytes < 0) {
        PyErr_SetString(PyExc_ValueError, "nbytes must be >= 0");
        return -1;
    }

    tSize bytes_read = hdfsRead(self->fs, self->file, buf, nbytes);
    if (bytes_read < 0) { // error
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    return bytes_read;
}

static PyObject* _read_new_pystr(FileInfo* self, Py_ssize_t nbytes) {

    if (nbytes < 0) { // read entire file
        nbytes = hdfsAvailable(self->fs, self->file);
        if (nbytes < 0) {
            PyErr_SetFromErrno(PyExc_IOError);
            return NULL;
        }
    }

    // Allocate an uninitialized string object.
    // We then access and directly modify the string's internal memory. This is
    // ok until we release this string "into the wild".
    PyObject* retval = PyString_FromStringAndSize(NULL, nbytes);
    if (!retval) return PyErr_NoMemory();

    Py_ssize_t bytes_read = _read_into_str(self, PyString_AS_STRING(retval), nbytes);

    if (bytes_read >= 0) {
        // If bytes_read >= 0, read worked properly. But, if bytes_read < nbytes
        // we got fewer bytes than requested (maybe we reached EOF?).  We need
        // to shrink the string to the correct length.  In case of error the
        // call to _PyString_Resize frees the original string, sets the
        // appropriate python exception and returns -1.
        if (bytes_read >= nbytes || _PyString_Resize(&retval, bytes_read) >= 0)
            return retval; // all good
    }

    // If we get here something's gone wrong.  The exception should already be set.
    Py_DECREF(retval);
    return NULL;
}

/*
 * Seek to `pos` and read `nbytes` bytes into a the provided buffer.
 *
 * \return: Number of bytes read. In case of error this function sets
 * the appropriate Python exception and returns -1.
 */
static Py_ssize_t _pread_into_str(FileInfo *self, char* buffer, Py_ssize_t pos, Py_ssize_t nbytes) {

    Py_ssize_t orig_position = hdfsTell(self->fs, self->file);
    if (orig_position < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    if (hdfsSeek(self->fs, self->file, pos) < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    tSize bytes_read = _read_into_str(self, buffer, nbytes);

    if (bytes_read < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    if (hdfsSeek(self->fs, self->file, orig_position) < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    return bytes_read;
}

static PyObject* _pread_new_pystr(FileInfo* self, Py_ssize_t pos, Py_ssize_t nbytes) {

    if (nbytes < 0) { // read entire file
        nbytes = hdfsAvailable(self->fs, self->file);
        if (nbytes < 0) {
            PyErr_SetFromErrno(PyExc_IOError);
            return NULL;
        }
    }

    // Allocate an uninitialized string object.
    PyObject* retval = PyString_FromStringAndSize(NULL, nbytes);
    if (!retval) return PyErr_NoMemory();

    Py_ssize_t bytes_read = _pread_into_str(self, PyString_AS_STRING(retval), pos, nbytes);

    if (bytes_read >= 0) {
        // If bytes_read >= 0, read worked properly. But, if bytes_read < nbytes
        // we got fewer bytes than requested (maybe we reached EOF?).  We need
        // to shrink the string to the correct length.  In case of error the
        // call to _PyString_Resize frees the original string, sets the
        // appropriate python exception and returns -1.
        if (bytes_read >= nbytes || _PyString_Resize(&retval, bytes_read) >= 0)
            return retval; // all good
    }

    // If we get here something's gone wrong.  The exception should already be set.
    Py_DECREF(retval);
    return NULL;
}

PyObject* FileClass_read(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_ssize_t nbytes;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "n", &(nbytes)))
        return NULL;

    if (nbytes < 0) {
        PyErr_SetString(PyExc_ValueError, "nbytes must be >= 0");
        return NULL;
    }
    else if (nbytes == 0) {
      return PyString_FromString("");
    }
    // else nbytes > 0

    return _read_new_pystr(self, nbytes);
}

PyObject* FileClass_read_chunk(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_buffer buffer;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "w*",  &buffer))
        return NULL;

    Py_ssize_t bytes_read = _read_into_str(self, (char*)buffer.buf, buffer.len);
    PyBuffer_Release(&buffer);

    if (bytes_read >= 0)
        return Py_BuildValue("n", bytes_read);
    else
        return NULL;
}

PyObject* FileClass_pread(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_ssize_t position;
    Py_ssize_t nbytes;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "nn", &position, &nbytes))
        return NULL;

    if (position < 0) {
        PyErr_SetString(PyExc_ValueError, "position must be >= 0");
        return NULL;
    }

    if (nbytes == 0)
      return PyString_FromString("");

    // else

    return _pread_new_pystr(self, position, nbytes);
}

PyObject* FileClass_pread_chunk(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_buffer buffer;
    Py_ssize_t position;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "nw*", &position, &buffer))
        return NULL;

    if (position < 0) {
        PyErr_SetString(PyExc_ValueError, "position must be >= 0");
        return NULL;
    }

    Py_ssize_t bytes_read = _pread_into_str(self, (char*)buffer.buf, position, buffer.len);
    PyBuffer_Release(&buffer);

    if (bytes_read >= 0)
        return Py_BuildValue("n", bytes_read);
    else
        return NULL;
}

PyObject* FileClass_seek(FileInfo *self, PyObject *args, PyObject *kwds){

    tOffset position;

    if (! PyArg_ParseTuple(args, "n", &position))
        return NULL;

    int result = hdfsSeek(self->fs, self->file, position);
    return Py_BuildValue("i", result);
}

PyObject* FileClass_tell(FileInfo *self, PyObject *args, PyObject *kwds){

    tOffset offset = hdfsTell(self->fs, self->file);
    return Py_BuildValue("n", offset);
}

PyObject* FileClass_write(FileInfo* self, PyObject *args, PyObject *kwds)
{

    char* buffer;
    int buffer_length;

    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForWrite(self)){
    #else
    if(!hdfsFileIsOpenForWrite(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in WRITE ('w') mode");
        return NULL;
    }

    if (! PyArg_ParseTuple(args, "s#",  &buffer, &buffer_length))
        return NULL;

    int written = hdfsWrite(self->fs, self->file, buffer, buffer_length);
    return Py_BuildValue("i", written);
}

PyObject* FileClass_write_chunk(FileInfo* self, PyObject *args, PyObject *kwds)
{

    char* buffer;
    int buffer_length;

    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForWrite(self)){
    #else
    if(!hdfsFileIsOpenForWrite(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in WRITE ('w') mode");
        return NULL;
    }

    if (! PyArg_ParseTuple(args, "s#", &buffer, &buffer_length))
        return NULL;

    int written = hdfsWrite(self->fs, self->file, buffer, buffer_length);
    return Py_BuildValue("i", written);
}

PyObject* FileClass_flush(FileInfo *self){
    int result = hdfsFlush(self->fs, self->file);
    return Py_BuildValue("i", result);
}

<commit_msg>Raise IOError on pos < 0 in hdfs_file.seek, like a Python file<commit_after>#include "hdfs_file.h"
#include "hdfs_utils.h"

using namespace std;

PyObject* FileClass_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    FileInfo *self;

    self = (FileInfo *)type->tp_alloc(type, 0);
    if (self != NULL) {
        self->fs = NULL;
        self->file = NULL;
        self->flags = 0;
        self->buff_size = 0;
        self->replication = 1;
        self->blocksize = 0;
        self->readline_chunk_size = 16 * 1024; // 16 KB
#ifdef HADOOP_LIBHDFS_V1
        self->stream_type = 0;
#endif
    }
    return (PyObject *)self;
}

#ifdef HADOOP_LIBHDFS_V1

bool hdfsFileIsOpenForWrite(FileInfo *f){
    return f->stream_type == OUTPUT;
}

bool hdfsFileIsOpenForRead(FileInfo *f){
    return f->stream_type == INPUT;
}

#endif

void FileClass_dealloc(FileInfo* self)
{
    self->file = NULL;
    self->ob_type->tp_free((PyObject*)self);
}

int FileClass_init(FileInfo *self, PyObject *args, PyObject *kwds)
{
    if (! PyArg_ParseTuple(args, "OO", &(self->fs), &(self->file))) {
        return -1;
    }

    return 0;
}

int FileClass_init_internal(FileInfo *self, hdfsFS fs, hdfsFile file)
{
    self->fs = fs;
    self->file = file;

    return 0;
}

PyObject* FileClass_close(FileInfo* self){
    int result = hdfsCloseFile(self->fs, self->file);
    if (result < 0) {
        return PyErr_SetFromErrno(PyExc_IOError);
    }
    else
        return PyBool_FromLong(1);
}

PyObject* FileClass_mode(FileInfo* self){
    return FileClass_get_mode(self);
}

PyObject* FileClass_get_mode(FileInfo *self){
    return PyLong_FromLong(self->flags);
}

PyObject* FileClass_available(FileInfo *self){
    int available = hdfsAvailable(self->fs, self->file);
    if (available < 0)
        return PyErr_SetFromErrno(PyExc_IOError);
    else
        return PyLong_FromLong(available);
}

static int _ensure_open_for_reading(FileInfo* self) {
    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForRead(self)){
    #else
    if(!hdfsFileIsOpenForRead(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in READ ('r') mode");
        return 0; // False
    }

    return 1; // True
}

static Py_ssize_t _read_into_str(FileInfo *self, char* buf, Py_ssize_t nbytes) {

    if (nbytes < 0) {
        PyErr_SetString(PyExc_ValueError, "nbytes must be >= 0");
        return -1;
    }

    tSize bytes_read = hdfsRead(self->fs, self->file, buf, nbytes);
    if (bytes_read < 0) { // error
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    return bytes_read;
}

static PyObject* _read_new_pystr(FileInfo* self, Py_ssize_t nbytes) {

    if (nbytes < 0) { // read entire file
        nbytes = hdfsAvailable(self->fs, self->file);
        if (nbytes < 0) {
            PyErr_SetFromErrno(PyExc_IOError);
            return NULL;
        }
    }

    // Allocate an uninitialized string object.
    // We then access and directly modify the string's internal memory. This is
    // ok until we release this string "into the wild".
    PyObject* retval = PyString_FromStringAndSize(NULL, nbytes);
    if (!retval) return PyErr_NoMemory();

    Py_ssize_t bytes_read = _read_into_str(self, PyString_AS_STRING(retval), nbytes);

    if (bytes_read >= 0) {
        // If bytes_read >= 0, read worked properly. But, if bytes_read < nbytes
        // we got fewer bytes than requested (maybe we reached EOF?).  We need
        // to shrink the string to the correct length.  In case of error the
        // call to _PyString_Resize frees the original string, sets the
        // appropriate python exception and returns -1.
        if (bytes_read >= nbytes || _PyString_Resize(&retval, bytes_read) >= 0)
            return retval; // all good
    }

    // If we get here something's gone wrong.  The exception should already be set.
    Py_DECREF(retval);
    return NULL;
}

/*
 * Seek to `pos` and read `nbytes` bytes into a the provided buffer.
 *
 * \return: Number of bytes read. In case of error this function sets
 * the appropriate Python exception and returns -1.
 */
static Py_ssize_t _pread_into_str(FileInfo *self, char* buffer, Py_ssize_t pos, Py_ssize_t nbytes) {

    Py_ssize_t orig_position = hdfsTell(self->fs, self->file);
    if (orig_position < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    if (hdfsSeek(self->fs, self->file, pos) < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    tSize bytes_read = _read_into_str(self, buffer, nbytes);

    if (bytes_read < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    if (hdfsSeek(self->fs, self->file, orig_position) < 0) {
        PyErr_SetFromErrno(PyExc_IOError);
        return -1;
    }

    return bytes_read;
}

static PyObject* _pread_new_pystr(FileInfo* self, Py_ssize_t pos, Py_ssize_t nbytes) {

    if (nbytes < 0) { // read entire file
        nbytes = hdfsAvailable(self->fs, self->file);
        if (nbytes < 0) {
            PyErr_SetFromErrno(PyExc_IOError);
            return NULL;
        }
    }

    // Allocate an uninitialized string object.
    PyObject* retval = PyString_FromStringAndSize(NULL, nbytes);
    if (!retval) return PyErr_NoMemory();

    Py_ssize_t bytes_read = _pread_into_str(self, PyString_AS_STRING(retval), pos, nbytes);

    if (bytes_read >= 0) {
        // If bytes_read >= 0, read worked properly. But, if bytes_read < nbytes
        // we got fewer bytes than requested (maybe we reached EOF?).  We need
        // to shrink the string to the correct length.  In case of error the
        // call to _PyString_Resize frees the original string, sets the
        // appropriate python exception and returns -1.
        if (bytes_read >= nbytes || _PyString_Resize(&retval, bytes_read) >= 0)
            return retval; // all good
    }

    // If we get here something's gone wrong.  The exception should already be set.
    Py_DECREF(retval);
    return NULL;
}

PyObject* FileClass_read(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_ssize_t nbytes;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "n", &(nbytes)))
        return NULL;

    if (nbytes < 0) {
        PyErr_SetString(PyExc_ValueError, "nbytes must be >= 0");
        return NULL;
    }
    else if (nbytes == 0) {
      return PyString_FromString("");
    }
    // else nbytes > 0

    return _read_new_pystr(self, nbytes);
}

PyObject* FileClass_read_chunk(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_buffer buffer;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "w*",  &buffer))
        return NULL;

    Py_ssize_t bytes_read = _read_into_str(self, (char*)buffer.buf, buffer.len);
    PyBuffer_Release(&buffer);

    if (bytes_read >= 0)
        return Py_BuildValue("n", bytes_read);
    else
        return NULL;
}

PyObject* FileClass_pread(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_ssize_t position;
    Py_ssize_t nbytes;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "nn", &position, &nbytes))
        return NULL;

    if (position < 0) {
        PyErr_SetString(PyExc_ValueError, "position must be >= 0");
        return NULL;
    }

    if (nbytes == 0)
      return PyString_FromString("");

    // else

    return _pread_new_pystr(self, position, nbytes);
}

PyObject* FileClass_pread_chunk(FileInfo *self, PyObject *args, PyObject *kwds){

    Py_buffer buffer;
    Py_ssize_t position;

    if (!_ensure_open_for_reading(self))
        return NULL;

    if (! PyArg_ParseTuple(args, "nw*", &position, &buffer))
        return NULL;

    if (position < 0) {
        PyErr_SetString(PyExc_ValueError, "position must be >= 0");
        return NULL;
    }

    Py_ssize_t bytes_read = _pread_into_str(self, (char*)buffer.buf, position, buffer.len);
    PyBuffer_Release(&buffer);

    if (bytes_read >= 0)
        return Py_BuildValue("n", bytes_read);
    else
        return NULL;
}

PyObject* FileClass_seek(FileInfo *self, PyObject *args, PyObject *kwds){

    tOffset position;

    if (! PyArg_ParseTuple(args, "n", &position))
        return NULL;

    if (position < 0) {
        // raise an IOError like a regular python file
        errno = EINVAL;
        PyErr_SetFromErrno(PyExc_IOError);
        errno = 0;
        return NULL;
    }

    int result = hdfsSeek(self->fs, self->file, position);
    return Py_BuildValue("i", result);
}

PyObject* FileClass_tell(FileInfo *self, PyObject *args, PyObject *kwds){

    tOffset offset = hdfsTell(self->fs, self->file);
    return Py_BuildValue("n", offset);
}

PyObject* FileClass_write(FileInfo* self, PyObject *args, PyObject *kwds)
{

    char* buffer;
    int buffer_length;

    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForWrite(self)){
    #else
    if(!hdfsFileIsOpenForWrite(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in WRITE ('w') mode");
        return NULL;
    }

    if (! PyArg_ParseTuple(args, "s#",  &buffer, &buffer_length))
        return NULL;

    int written = hdfsWrite(self->fs, self->file, buffer, buffer_length);
    return Py_BuildValue("i", written);
}

PyObject* FileClass_write_chunk(FileInfo* self, PyObject *args, PyObject *kwds)
{

    char* buffer;
    int buffer_length;

    #ifdef HADOOP_LIBHDFS_V1
    if(!hdfsFileIsOpenForWrite(self)){
    #else
    if(!hdfsFileIsOpenForWrite(self->file)){
    #endif
        PyErr_SetString(PyExc_IOError, "File is not opened in WRITE ('w') mode");
        return NULL;
    }

    if (! PyArg_ParseTuple(args, "s#", &buffer, &buffer_length))
        return NULL;

    int written = hdfsWrite(self->fs, self->file, buffer, buffer_length);
    return Py_BuildValue("i", written);
}

PyObject* FileClass_flush(FileInfo *self){
    int result = hdfsFlush(self->fs, self->file);
    return Py_BuildValue("i", result);
}

<|endoftext|>


<commit_before>#include "stdafx.h"
#include "HelperDefinitions.h"

namespace helper
{
	StringW to_wide( const String8 &str )
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
		try
		{
			return converter.from_bytes( str );
		}
		catch( std::range_error error )
		{
			log( "Conversation failure 'to_wide(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
			return L"";
		}
	}

	String8 to_utf8( const StringW &str )
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
		try
		{
			return converter.to_bytes( str );
		}
		catch( std::range_error error )
		{
			log( "Conversation failure 'to_utf8(const StringW &)'. Message: " + String8( error.what() ), LogLevel::Warning );
			return "";
		}
	}

	#if (_MSC_VER == 1900 || _MSC_VER == 1910) //bug-workaround (VC_2015)

		String8 to_utf8( const String16 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int16_t>, int16_t> converter;
			try
			{
				auto p = reinterpret_cast<const int16_t *>( str.data() );
				return converter.to_bytes( p, p + str.size() );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String16 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String8 to_utf8( const String32 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> converter;
			try
			{
				auto p = reinterpret_cast<const int32_t *>( str.data() );
				return converter.to_bytes( p, p + str.size() );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String32 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String16 to_utf16( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int16_t>, int16_t> converter;
			try
			{
				auto p = converter.from_bytes( str );
				return String16( reinterpret_cast<const char16_t *>( p.data() ) );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf16(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return u"";
			}
		}
		String32 to_utf32( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> converter;
			try
			{
				auto p = converter.from_bytes( str );
				return String32( reinterpret_cast<const char32_t *>( p.data() ) );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf32(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return U"";
			}
		}

	#else

		String8 to_utf8( const String16 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
			try
			{
				return converter.to_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String16 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String8 to_utf8( const String32 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
			try
			{
				return converter.to_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String32 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String16 to_utf16( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
			try
			{
				return converter.from_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf16(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return u"";
			}
		}
		String32 to_utf32( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
			try
			{
				return converter.from_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf32(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return U"";
			}
		}
	#endif

	template<>
	std::string int_to_hex( s8 i )
	{
		std::stringstream stream;
		stream << std::setfill( '0' ) << std::setw( 2 )
			<< std::hex << static_cast<int>( i );
		return stream.str();
	}
	template<>
	std::string int_to_hex( u8 i )
	{
		std::stringstream stream;
		stream << std::setfill( '0' ) << std::setw( 2 )
			<< std::hex << static_cast<int>( i );
		return stream.str();
	}

	inline void log( const String8 &text, LogLevel level )
	{
		logMultiline( text + '\n', level );
	}
	inline void logMultiline( const String8 &text, LogLevel level )
	{
		static std::recursive_mutex mx;
		std::lock_guard<std::recursive_mutex> lock( mx );

		#ifdef _WIN32
		OutputDebugStringW( to_wide( String8( level == LogLevel::Debug ? "D" : level == LogLevel::Information ? "I" : level == LogLevel::Warning ? "W" : level == LogLevel::Error ? "E" : "UKN" ) + "/ " + text ).c_str() );

		HANDLE  consoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );
		if( level == LogLevel::Debug ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_GREEN | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Information ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Warning )SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Error ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_INTENSITY );
		#endif // _WIN32

		if( level == LogLevel::Error || level == LogLevel::Warning )
		{
			std::wcerr << to_wide( text );
		}
		else
		{
			std::wcout << to_wide( text );
		}
		#ifdef _WIN32
		SetConsoleTextAttribute( consoleHandle, 7 );//Reset color
		#endif // _WIN32
	}

	fs::path resolve( const fs::path &p, const fs::path &base )
	{
		fs::path ret;
		fs::path absolute = fs::absolute( p, base );

		for( fs::path::iterator it = absolute.begin() ; it != absolute.end() ; it++ )
		{
			if( *it == ".." )
			{//Go one dir backwars
				if( fs::is_symlink( ret ) )
				{//Check for symlinks
					ret /= *it;
				}
				else if( ret.filename() == ".." )
				{//Multiple ..s'
					ret /= *it;
				}
				// Otherwise it should be safe to resolve the parent
				else
					ret = ret.parent_path();
			}
			else if( *it == "." );//Ignore
			else
			{//Normal dirs
				ret /= *it;
			}
		}
		return ret;
	}
}
<commit_msg>Fixed bug with newer visual studio compiler<commit_after>#include "stdafx.h"
#include "HelperDefinitions.h"

namespace helper
{
	StringW to_wide( const String8 &str )
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
		try
		{
			return converter.from_bytes( str );
		}
		catch( std::range_error error )
		{
			log( "Conversation failure 'to_wide(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
			return L"";
		}
	}

	String8 to_utf8( const StringW &str )
	{
		std::wstring_convert<std::codecvt_utf8<wchar_t>> converter;
		try
		{
			return converter.to_bytes( str );
		}
		catch( std::range_error error )
		{
			log( "Conversation failure 'to_utf8(const StringW &)'. Message: " + String8( error.what() ), LogLevel::Warning );
			return "";
		}
	}

	#if (_MSC_VER >= 1900 && _MSC_VER <= 1911) //bug-workaround (VC_2015+)

		String8 to_utf8( const String16 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int16_t>, int16_t> converter;
			try
			{
				auto p = reinterpret_cast<const int16_t *>( str.data() );
				return converter.to_bytes( p, p + str.size() );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String16 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String8 to_utf8( const String32 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> converter;
			try
			{
				auto p = reinterpret_cast<const int32_t *>( str.data() );
				return converter.to_bytes( p, p + str.size() );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String32 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String16 to_utf16( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int16_t>, int16_t> converter;
			try
			{
				auto p = converter.from_bytes( str );
				return String16( reinterpret_cast<const char16_t *>( p.data() ) );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf16(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return u"";
			}
		}
		String32 to_utf32( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<int32_t>, int32_t> converter;
			try
			{
				auto p = converter.from_bytes( str );
				return String32( reinterpret_cast<const char32_t *>( p.data() ) );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf32(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return U"";
			}
		}

	#else

		String8 to_utf8( const String16 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
			try
			{
				return converter.to_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String16 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String8 to_utf8( const String32 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
			try
			{
				return converter.to_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf8(const String32 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return "";
			}
		}
		String16 to_utf16( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char16_t>, char16_t> converter;
			try
			{
				return converter.from_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf16(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return u"";
			}
		}
		String32 to_utf32( const String8 &str )
		{
			std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> converter;
			try
			{
				return converter.from_bytes( str );
			}
			catch( std::range_error error )
			{
				log( "Conversation failure 'to_utf32(const String8 &)'. Message: " + String8( error.what() ), LogLevel::Warning );
				return U"";
			}
		}
	#endif

	template<>
	std::string int_to_hex( s8 i )
	{
		std::stringstream stream;
		stream << std::setfill( '0' ) << std::setw( 2 )
			<< std::hex << static_cast<int>( i );
		return stream.str();
	}
	template<>
	std::string int_to_hex( u8 i )
	{
		std::stringstream stream;
		stream << std::setfill( '0' ) << std::setw( 2 )
			<< std::hex << static_cast<int>( i );
		return stream.str();
	}

	inline void log( const String8 &text, LogLevel level )
	{
		logMultiline( text + '\n', level );
	}
	inline void logMultiline( const String8 &text, LogLevel level )
	{
		static std::recursive_mutex mx;
		std::lock_guard<std::recursive_mutex> lock( mx );

		#ifdef _WIN32
		OutputDebugStringW( to_wide( String8( level == LogLevel::Debug ? "D" : level == LogLevel::Information ? "I" : level == LogLevel::Warning ? "W" : level == LogLevel::Error ? "E" : "UKN" ) + "/ " + text ).c_str() );

		HANDLE  consoleHandle = GetStdHandle( STD_OUTPUT_HANDLE );
		if( level == LogLevel::Debug ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_GREEN | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Information ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Warning )SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_INTENSITY );
		else if( level == LogLevel::Error ) SetConsoleTextAttribute( consoleHandle, FOREGROUND_RED | FOREGROUND_INTENSITY );
		#endif // _WIN32

		if( level == LogLevel::Error || level == LogLevel::Warning )
		{
			std::wcerr << to_wide( text );
		}
		else
		{
			std::wcout << to_wide( text );
		}
		#ifdef _WIN32
		SetConsoleTextAttribute( consoleHandle, 7 );//Reset color
		#endif // _WIN32
	}

	fs::path resolve( const fs::path &p, const fs::path &base )
	{
		fs::path ret;
		fs::path absolute = fs::absolute( p, base );

		for( fs::path::iterator it = absolute.begin() ; it != absolute.end() ; it++ )
		{
			if( *it == ".." )
			{//Go one dir backwars
				if( fs::is_symlink( ret ) )
				{//Check for symlinks
					ret /= *it;
				}
				else if( ret.filename() == ".." )
				{//Multiple ..s'
					ret /= *it;
				}
				// Otherwise it should be safe to resolve the parent
				else
					ret = ret.parent_path();
			}
			else if( *it == "." );//Ignore
			else
			{//Normal dirs
				ret /= *it;
			}
		}
		return ret;
	}
}
<|endoftext|>


<commit_before>#include <HTTPClient.h>
#include <ESP32WebServer.h>
#include <Arduino.h>
#include <ArduinoJson.h>

#include "PacmanServer.h"

PacmanServer::PacmanServer(String registerUrl, String algorithmUrl, String name, int serverPort)
:server(serverPort),
gameStatus(PLAYING),
quarantaine(0),
score(0),
lives(3)
{
	int httpCode = 0;
	//register to server
	do
	{
		http.begin(registerUrl);
		String message = "{ \"name\": \"" + name + "\" }";
		httpCode = http.POST(message);
	} while (httpCode != HTTP_CODE_OK);

	DynamicJsonBuffer jsonBuffer;
	String registrationResponse = http.getString();
	http.end();

	//set local variables
	JsonObject& root = jsonBuffer.parseObject(registrationResponse);
	if (root["type"] == "pacman")
	{
		character = PACMAN;
	}
	else
	{
		character = GHOST;
	}

	//start connection with algorithmserver
	http.begin(algorithmUrl);
	http.setReuse(true);
	http.addHeader("Content-Type", "application/json");
	http.POST(registrationResponse);

	//setting up server on device
	server.begin();
	server.on("/event/location", std::bind(&PacmanServer::event_location, this));
	server.on("/event/location_error", std::bind(&PacmanServer::event_location_error, this));
	server.on("/event/food", std::bind(&PacmanServer::event_food, this));
	server.on("/event/cherry", std::bind(&PacmanServer::event_cherry, this));
	server.on("/event/energizer", std::bind(&PacmanServer::event_energizer, this));
	server.on("/event/cherry_spawned", std::bind(&PacmanServer::event_cherry_spawned, this));
	server.on("/event/collision", std::bind(&PacmanServer::event_collision, this));
	server.on("/event/quarantine", std::bind(&PacmanServer::event_quarantine, this));
	server.on("/event/game_over", std::bind(&PacmanServer::event_game_over, this));
	server.on("/event/game_won", std::bind(&PacmanServer::event_game_won, this));
}

PacmanServer::~PacmanServer()
{
	http.end();
	server.close();
}

void PacmanServer::handleEvents()
{
	server.handleClient();
}

void PacmanServer::setLocation(int x_pixel, int y_pixel)
{
	posX= 5* x_pixel;
	posY= 5* y_pixel;
}

Role PacmanServer::getRole()
{
	return character;
}

int PacmanServer::getScore()
{
	return score;
}

int PacmanServer::getLives()
{
	return lives;
}

bool PacmanServer::inQuarantaine()
{
	if (millis() > quarantaine)
	{
		return false;
	}
	else
	{
		return true;
	}
}

Status	PacmanServer::getGameStatus()
{
	return gameStatus;
}

void PacmanServer::event_location()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "{\"x\":" + String(posX) + ",\"y\":"+String(posY)+"}");
}

void PacmanServer::event_location_error()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_food()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");

}

void PacmanServer::event_cherry()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_energizer()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_cherry_spawned()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_collision()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_quarantine()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
	quarantaine = millis() + 10000;
}

void PacmanServer::event_game_over()
{
	StaticJsonBuffer<JSON_OBJECT_SIZE(3)> jsonBuffer;
	JsonObject& root = jsonBuffer.parseObject(server.arg(0));
	lives = root["lives"];
	score = root["score"];
	server.send(200, "application/json; charset=utf-8", "");
	gameStatus = LOST;
}

void PacmanServer::event_game_won()
{
	StaticJsonBuffer<JSON_OBJECT_SIZE(3)> jsonBuffer;
	JsonObject& root = jsonBuffer.parseObject(server.arg(0));
	lives = root["lives"];
	score = root["score"];
	server.send(200, "application/json; charset=utf-8", "");
	gameStatus = WON;
}<commit_msg>Jsonbuffersize definition added<commit_after>#include <HTTPClient.h>
#include <ESP32WebServer.h>
#include <Arduino.h>
#include <ArduinoJson.h>

#include "PacmanServer.h"

PacmanServer::PacmanServer(String registerUrl, String algorithmUrl, String name, int serverPort)
:server(serverPort),
gameStatus(PLAYING),
quarantaine(0),
score(0),
lives(3)
{
	int httpCode = 0;
	//register to server
	do
	{
		http.begin(registerUrl);
		String message = "{ \"name\": \"" + name + "\" }";
		httpCode = http.POST(message);
	} while (httpCode != HTTP_CODE_OK);

	const size_t bufferSize = JSON_ARRAY_SIZE(4) + JSON_ARRAY_SIZE(62) + 66*JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 1180;
	DynamicJsonBuffer jsonBuffer(bufferSize);
	String registrationResponse = http.getString();
	http.end();

	//set local variables
	JsonObject& root = jsonBuffer.parseObject(registrationResponse);
	if (root["type"] == "pacman")
	{
		character = PACMAN;
	}
	else
	{
		character = GHOST;
	}

	//start connection with algorithmserver
	http.begin(algorithmUrl);
	http.setReuse(true);
	http.addHeader("Content-Type", "application/json");
	http.POST(registrationResponse);

	//setting up server on device
	server.begin();
	server.on("/event/location", std::bind(&PacmanServer::event_location, this));
	server.on("/event/location_error", std::bind(&PacmanServer::event_location_error, this));
	server.on("/event/food", std::bind(&PacmanServer::event_food, this));
	server.on("/event/cherry", std::bind(&PacmanServer::event_cherry, this));
	server.on("/event/energizer", std::bind(&PacmanServer::event_energizer, this));
	server.on("/event/cherry_spawned", std::bind(&PacmanServer::event_cherry_spawned, this));
	server.on("/event/collision", std::bind(&PacmanServer::event_collision, this));
	server.on("/event/quarantine", std::bind(&PacmanServer::event_quarantine, this));
	server.on("/event/game_over", std::bind(&PacmanServer::event_game_over, this));
	server.on("/event/game_won", std::bind(&PacmanServer::event_game_won, this));
}

PacmanServer::~PacmanServer()
{
	http.end();
	server.close();
}

void PacmanServer::handleEvents()
{
	server.handleClient();
}

void PacmanServer::setLocation(int x_pixel, int y_pixel)
{
	posX= 5* x_pixel;
	posY= 5* y_pixel;
}

Role PacmanServer::getRole()
{
	return character;
}

int PacmanServer::getScore()
{
	return score;
}

int PacmanServer::getLives()
{
	return lives;
}

bool PacmanServer::inQuarantaine()
{
	if (millis() > quarantaine)
	{
		return false;
	}
	else
	{
		return true;
	}
}

Status	PacmanServer::getGameStatus()
{
	return gameStatus;
}

void PacmanServer::event_location()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "{\"x\":" + String(posX) + ",\"y\":"+String(posY)+"}");
}

void PacmanServer::event_location_error()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_food()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");

}

void PacmanServer::event_cherry()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_energizer()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_cherry_spawned()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_collision()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
}

void PacmanServer::event_quarantine()
{
	http.addHeader("Content-Type", "application/json");
	http.POST(server.arg(0));
	server.send(200, "application/json; charset=utf-8", "");
	quarantaine = millis() + 10000;
}

void PacmanServer::event_game_over()
{
	StaticJsonBuffer<JSON_OBJECT_SIZE(3)> jsonBuffer;
	JsonObject& root = jsonBuffer.parseObject(server.arg(0));
	lives = root["lives"];
	score = root["score"];
	server.send(200, "application/json; charset=utf-8", "");
	gameStatus = LOST;
}

void PacmanServer::event_game_won()
{
	StaticJsonBuffer<JSON_OBJECT_SIZE(3)> jsonBuffer;
	JsonObject& root = jsonBuffer.parseObject(server.arg(0));
	lives = root["lives"];
	score = root["score"];
	server.send(200, "application/json; charset=utf-8", "");
	gameStatus = WON;
}<|endoftext|>