<commit_before>
#include "phonon_test.h"
#include <experimental/globalconfig.h>

MediaPlayer::MediaPlayer(QWidget *parent)
: QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    m_vwidget = new Phonon::VideoWidget(this);
    m_vwidget->setMinimumSize(QSize(400, 300));
    layout->addWidget(m_vwidget);

    m_aoutput = new Phonon::AudioOutput();

    m_media = new Phonon::MediaObject();

    Phonon::createPath(m_media, m_aoutput);
    Phonon::createPath(m_media, m_vwidget);

    QHBoxLayout *urlLayout = new QHBoxLayout(this);

    m_deviceNameEdit = new QLineEdit(this);
    m_deviceNameEdit->setText("URL");
    urlLayout->addWidget(m_deviceNameEdit);
    connect(m_deviceNameEdit, SIGNAL(editingFinished()), this, SLOT(setDeviceName()));

    layout->addItem(urlLayout);

    m_playButton = new QPushButton(this);
    m_playButton->setText("Play");
    layout->addWidget(m_playButton);
    connect(m_playButton, SIGNAL(clicked()), m_media, SLOT(play()));

    m_volumeSlider = new Phonon::VolumeSlider(this);
    layout->addWidget(m_volumeSlider);
    m_volumeSlider->setAudioOutput(m_aoutput);

    setLayout(layout);
}

MediaPlayer::~MediaPlayer()
{
    delete m_aoutput;
}

void MediaPlayer::setDeviceName()
{
    Phonon::MediaSource mediaSource(Phonon::V4LVideo, m_deviceNameEdit->text());
    m_media->setCurrentSource(mediaSource);
    m_media->play();
}

<commit_msg>Capture app: Set default device name to /dev/video0<commit_after>
#include "phonon_test.h"
#include <experimental/globalconfig.h>

MediaPlayer::MediaPlayer(QWidget *parent)
: QWidget(parent)
{
    QVBoxLayout *layout = new QVBoxLayout(this);

    m_vwidget = new Phonon::VideoWidget(this);
    m_vwidget->setMinimumSize(QSize(400, 300));
    layout->addWidget(m_vwidget);

    m_aoutput = new Phonon::AudioOutput();

    m_media = new Phonon::MediaObject();

    Phonon::createPath(m_media, m_aoutput);
    Phonon::createPath(m_media, m_vwidget);

    QHBoxLayout *urlLayout = new QHBoxLayout(this);

    m_deviceNameEdit = new QLineEdit(this);
    m_deviceNameEdit->setText("/dev/video0");
    urlLayout->addWidget(m_deviceNameEdit);
    connect(m_deviceNameEdit, SIGNAL(editingFinished()), this, SLOT(setDeviceName()));

    layout->addItem(urlLayout);

    m_playButton = new QPushButton(this);
    m_playButton->setText("Play");
    layout->addWidget(m_playButton);
    connect(m_playButton, SIGNAL(clicked()), m_media, SLOT(play()));

    m_volumeSlider = new Phonon::VolumeSlider(this);
    layout->addWidget(m_volumeSlider);
    m_volumeSlider->setAudioOutput(m_aoutput);

    setLayout(layout);
}

MediaPlayer::~MediaPlayer()
{
    delete m_aoutput;
}

void MediaPlayer::setDeviceName()
{
    Phonon::MediaSource mediaSource(Phonon::V4LVideo, m_deviceNameEdit->text());
    m_media->setCurrentSource(mediaSource);
    m_media->play();
}

<|endoftext|>


<commit_before>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Common.hpp"
# include "FormatData.hpp"

# if SIV3D_INTRINSIC(SSE)
    # define _XM_SSE4_INTRINSICS_
# endif

# if defined(__GNUC__) && !defined(__clang__)
#	pragma GCC diagnostic push
#	pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# endif
SIV3D_DISABLE_MSVC_WARNINGS_PUSH(4459)
# include <ThirdParty/DirectXMath/DirectXMath.h>
# include <ThirdParty/DirectXMath/DirectXCollision.h>
SIV3D_DISABLE_MSVC_WARNINGS_POP()
# ifdef __GNUC__
#	pragma GCC diagnostic pop
# endif

 # if !SIV3D_PLATFORM(WINDOWS)
    # undef __in
    # undef __out
    # undef __valid
# endif

namespace s3d
{
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)

    using aligned_float4 = __m128;

#elif defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)

    using aligned_float4 = float32x4_t;

#else

    using aligned_float4 = __vector4;

#endif

# define SIV3D_VECTOR_CALL XM_CALLCONV

    void Formatter(FormatData& formatData, aligned_float4 value);
}
<commit_msg>[共通__vector4 to DirectX::__vector4<commit_after>//-----------------------------------------------
//
//	This file is part of the Siv3D Engine.
//
//	Copyright (c) 2008-2021 Ryo Suzuki
//	Copyright (c) 2016-2021 OpenSiv3D Project
//
//	Licensed under the MIT License.
//
//-----------------------------------------------

# pragma once
# include "Common.hpp"
# include "FormatData.hpp"

# if SIV3D_INTRINSIC(SSE)
    # define _XM_SSE4_INTRINSICS_
# endif

# if defined(__GNUC__) && !defined(__clang__)
#	pragma GCC diagnostic push
#	pragma GCC diagnostic ignored "-Wunused-but-set-variable"
# endif
SIV3D_DISABLE_MSVC_WARNINGS_PUSH(4459)
# include <ThirdParty/DirectXMath/DirectXMath.h>
# include <ThirdParty/DirectXMath/DirectXCollision.h>
SIV3D_DISABLE_MSVC_WARNINGS_POP()
# ifdef __GNUC__
#	pragma GCC diagnostic pop
# endif

 # if !SIV3D_PLATFORM(WINDOWS)
    # undef __in
    # undef __out
    # undef __valid
# endif

namespace s3d
{
#if defined(_XM_SSE_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)

    using aligned_float4 = __m128;

#elif defined(_XM_ARM_NEON_INTRINSICS_) && !defined(_XM_NO_INTRINSICS_)

    using aligned_float4 = float32x4_t;

#else

    using aligned_float4 = DirectX::__vector4;

#endif

# define SIV3D_VECTOR_CALL XM_CALLCONV

    void Formatter(FormatData& formatData, aligned_float4 value);
}
<|endoftext|>


<commit_before>
<commit_msg>Update ShellSort.cpp<commit_after>/* Shell Sort: 插入排序的扩展，将待排序的数组按照步长 gap 进行分组，然后将每组的元素利用插入排序的方法进行排序，直到 gap 为 1，利用插入完成排序。
 */

#include <iostream>

using namespace std;

template <typename T>
void shellsort(T arr[], int n)
{
    int gap = 1;

    while (gap < n / 3)
    {
        gap = gap * 3 + 1;  // 步长 gap
    }

    while (gap >= 1)
    {
        for (int i = gap; i < n; i++)
        {
            T temp = arr[i];

            int j = i;

            while (j >= gap && arr[j - gap] > temp)
            {
                arr[j] = arr[j - gap];
                j = j - gap;
            }

            arr[j] = temp;
        }

        gap = gap / 3;
    }
}

int main()
{
    int arr[] = {2, 5, 10, 4, 3, 1, 6, 8, 7, 9};

    int arrLength = sizeof(arr) / sizeof(arr[0]);

    shellsort(arr, arrLength);

    for (int i = 0; i < arrLength; i++) {
        cout << arr[i] << " ";
    }

    cout << endl;

    return 0;
}
<|endoftext|>


<commit_before>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Access to Android internals that are not a part of the NDK.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidInternals.hpp"
#include "deMemory.h"
#include "deStringUtil.hpp"

namespace tcu
{
namespace Android
{
namespace internal
{

using std::string;
using de::DynamicLibrary;

template<typename Func>
void setFuncPtr (Func*& funcPtr, DynamicLibrary& lib, const string& symname)
{
	funcPtr = reinterpret_cast<Func*>(lib.getFunction(symname.c_str()));
	if (!funcPtr)
		TCU_THROW(NotSupportedError, ("Unable to look up symbol from shared object: " + symname).c_str());
}

LibUI::LibUI (void)
	: m_library	("libui.so")
{
	GraphicBufferFunctions& gb = m_functions.graphicBuffer;

	setFuncPtr(gb.constructor,		m_library,	"_ZN7android13GraphicBufferC1Ejjij");
	setFuncPtr(gb.destructor,		m_library,	"_ZN7android13GraphicBufferD1Ev");
	setFuncPtr(gb.getNativeBuffer,	m_library,	"_ZNK7android13GraphicBuffer15getNativeBufferEv");
	setFuncPtr(gb.lock,				m_library,	"_ZN7android13GraphicBuffer4lockEjPPv");
	setFuncPtr(gb.unlock,			m_library,	"_ZN7android13GraphicBuffer6unlockEv");
	setFuncPtr(gb.initCheck,		m_library,	"_ZNK7android13GraphicBuffer9initCheckEv");
}

#define GRAPHICBUFFER_SIZE 1024 // Hopefully enough

typedef void (*GenericFptr)();

//! call constructor with 4 arguments
template <typename RT, typename T1, typename T2, typename T3, typename T4>
RT* callConstructor4 (GenericFptr fptr, void* memory, size_t memorySize, T1 param1, T2 param2, T3 param3, T4 param4)
{
	DE_UNREF(memorySize);

#if (DE_CPU == DE_CPU_ARM)
	// C1 constructors return pointer
	typedef RT* (*ABIFptr)(void*, T1, T2, T3, T4);
	(void)((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_ARM_64)
	// C1 constructors return void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_X86)
	// ctor returns void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_X86_64)
	// ctor returns void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#else
	TCU_THROW(NotSupportedError, "ABI not supported");
	return DE_NULL;
#endif
}

template <typename T>
void callDestructor (GenericFptr fptr, T* obj)
{
#if (DE_CPU == DE_CPU_ARM)
	// D1 destructor returns ptr
	typedef void* (*ABIFptr)(T* obj);
	(void)((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_ARM_64)
	// D1 destructor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_X86)
	// dtor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_X86_64)
	// dtor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#else
	TCU_THROW(NotSupportedError, "ABI not supported");
#endif
}

template<typename T1, typename T2>
T1* pointerToOffset (T2* ptr, size_t bytes)
{
	return reinterpret_cast<T1*>((deUint8*)ptr + bytes);
}

static android::android_native_base_t* getAndroidNativeBase (android::GraphicBuffer* gb)
{
	// \note: assuming Itanium ABI
	return pointerToOffset<android::android_native_base_t>(gb, 2 * DE_PTR_SIZE);
}

//! android_native_base_t::magic for ANativeWindowBuffer
static deInt32 getExpectedNativeBufferVersion (void)
{
#if (DE_PTR_SIZE == 4)
	return 96;
#elif (DE_PTR_SIZE == 8)
	return 168;
#else
#	error Invalid DE_PTR_SIZE
#endif
}

//! access android_native_base_t::magic
static deUint32 getNativeBaseMagic (android::android_native_base_t* base)
{
	return *pointerToOffset<deUint32>(base, 0);
}

//! access android_native_base_t::version
static deUint32 getNativeBaseVersion (android::android_native_base_t* base)
{
	return *pointerToOffset<deInt32>(base, 4);
}

//! access android_native_base_t::incRef
static NativeBaseFunctions::incRefFunc getNativeBaseIncRefFunc (android::android_native_base_t* base)
{
	return *pointerToOffset<NativeBaseFunctions::incRefFunc>(base, 8 + DE_PTR_SIZE*4);
}

//! access android_native_base_t::decRef
static NativeBaseFunctions::decRefFunc getNativeBaseDecRefFunc (android::android_native_base_t* base)
{
	return *pointerToOffset<NativeBaseFunctions::decRefFunc>(base, 8 + DE_PTR_SIZE*5);
}

static android::GraphicBuffer* createGraphicBuffer (const GraphicBufferFunctions& functions, NativeBaseFunctions& baseFunctions, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage)
{
	// \note: Hopefully uses the same allocator as libui
	void* const memory = deMalloc(GRAPHICBUFFER_SIZE);
	if (memory == DE_NULL)
		TCU_THROW(ResourceError, "Could not alloc for GraphicBuffer");
	else
	{
		try
		{
			android::GraphicBuffer* const			gb			= callConstructor4<android::GraphicBuffer, deUint32, deUint32, PixelFormat, deUint32>(functions.constructor,
																																					  memory,
																																					  GRAPHICBUFFER_SIZE,
																																					  w,
																																					  h,
																																					  format,
																																					  usage);
			android::android_native_base_t* const	base		= getAndroidNativeBase(gb);
			status_t								ctorStatus	= functions.initCheck(gb);

			if (ctorStatus)
			{
				// ctor failed
				callDestructor<android::GraphicBuffer>(functions.destructor, gb);
				TCU_THROW(NotSupportedError, ("GraphicBuffer ctor failed, initCheck returned " + de::toString(ctorStatus)).c_str());
			}

			// check object layout
			{
				const deUint32 magic		= getNativeBaseMagic(base);
				const deUint32 bufferMagic	= 0x5f626672u; // "_bfr"

				if (magic != bufferMagic)
					TCU_THROW(NotSupportedError, "GraphicBuffer layout unexpected");
			}

			// check object version
			{
				const deInt32 version			= getNativeBaseVersion(base);
				const deInt32 expectedVersion	= getExpectedNativeBufferVersion();

				if (version != expectedVersion)
					TCU_THROW(NotSupportedError, "GraphicBuffer version unexpected");
			}

			// locate refcounting functions

			if (!baseFunctions.incRef || !baseFunctions.decRef)
			{
				baseFunctions.incRef = getNativeBaseIncRefFunc(base);
				baseFunctions.decRef = getNativeBaseDecRefFunc(base);
			}

			// take the initial reference and return
			baseFunctions.incRef(base);
			return gb;
		}
		catch (...)
		{
			deFree(memory);
			throw;
		}
	}
}

GraphicBuffer::GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage)
	: m_functions	(lib.getFunctions().graphicBuffer)
	, m_impl		(DE_NULL)
{
	m_baseFunctions.incRef = DE_NULL;
	m_baseFunctions.decRef = DE_NULL;

	// \note createGraphicBuffer updates m_baseFunctions
	m_impl = createGraphicBuffer(m_functions, m_baseFunctions, width, height, format, usage);
}

GraphicBuffer::~GraphicBuffer (void)
{
	if (m_impl && m_baseFunctions.decRef)
	{
		m_baseFunctions.decRef(getAndroidNativeBase(m_impl));
		m_impl = DE_NULL;
	}
}

status_t GraphicBuffer::lock (deUint32 usage, void** vaddr)
{
	return m_functions.lock(m_impl, usage, vaddr);
}

status_t GraphicBuffer::unlock (void)
{
	return m_functions.unlock(m_impl);
}

ANativeWindowBuffer* GraphicBuffer::getNativeBuffer (void) const
{
	return m_functions.getNativeBuffer(m_impl);
}

} // internal
} // Android
} // tcu
<commit_msg>Fix GraphicBuffer warnings on mips and mips64.<commit_after>/*-------------------------------------------------------------------------
 * drawElements Quality Program Tester Core
 * ----------------------------------------
 *
 * Copyright 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Access to Android internals that are not a part of the NDK.
 *//*--------------------------------------------------------------------*/

#include "tcuAndroidInternals.hpp"
#include "deMemory.h"
#include "deStringUtil.hpp"

namespace tcu
{
namespace Android
{
namespace internal
{

using std::string;
using de::DynamicLibrary;

template<typename Func>
void setFuncPtr (Func*& funcPtr, DynamicLibrary& lib, const string& symname)
{
	funcPtr = reinterpret_cast<Func*>(lib.getFunction(symname.c_str()));
	if (!funcPtr)
		TCU_THROW(NotSupportedError, ("Unable to look up symbol from shared object: " + symname).c_str());
}

LibUI::LibUI (void)
	: m_library	("libui.so")
{
	GraphicBufferFunctions& gb = m_functions.graphicBuffer;

	setFuncPtr(gb.constructor,		m_library,	"_ZN7android13GraphicBufferC1Ejjij");
	setFuncPtr(gb.destructor,		m_library,	"_ZN7android13GraphicBufferD1Ev");
	setFuncPtr(gb.getNativeBuffer,	m_library,	"_ZNK7android13GraphicBuffer15getNativeBufferEv");
	setFuncPtr(gb.lock,				m_library,	"_ZN7android13GraphicBuffer4lockEjPPv");
	setFuncPtr(gb.unlock,			m_library,	"_ZN7android13GraphicBuffer6unlockEv");
	setFuncPtr(gb.initCheck,		m_library,	"_ZNK7android13GraphicBuffer9initCheckEv");
}

#define GRAPHICBUFFER_SIZE 1024 // Hopefully enough

typedef void (*GenericFptr)();

//! call constructor with 4 arguments
template <typename RT, typename T1, typename T2, typename T3, typename T4>
RT* callConstructor4 (GenericFptr fptr, void* memory, size_t memorySize, T1 param1, T2 param2, T3 param3, T4 param4)
{
	DE_UNREF(memorySize);

#if (DE_CPU == DE_CPU_ARM)
	// C1 constructors return pointer
	typedef RT* (*ABIFptr)(void*, T1, T2, T3, T4);
	(void)((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_ARM_64)
	// C1 constructors return void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_X86)
	// ctor returns void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#elif (DE_CPU == DE_CPU_X86_64)
	// ctor returns void
	typedef void (*ABIFptr)(void*, T1, T2, T3, T4);
	((ABIFptr)fptr)(memory, param1, param2, param3, param4);
	return reinterpret_cast<RT*>(memory);
#else
	DE_UNREF(fptr);
	DE_UNREF(memory);
	DE_UNREF(param1);
	DE_UNREF(param2);
	DE_UNREF(param3);
	DE_UNREF(param4);
	TCU_THROW(NotSupportedError, "ABI not supported");
	return DE_NULL;
#endif
}

template <typename T>
void callDestructor (GenericFptr fptr, T* obj)
{
#if (DE_CPU == DE_CPU_ARM)
	// D1 destructor returns ptr
	typedef void* (*ABIFptr)(T* obj);
	(void)((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_ARM_64)
	// D1 destructor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_X86)
	// dtor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#elif (DE_CPU == DE_CPU_X86_64)
	// dtor returns void
	typedef void (*ABIFptr)(T* obj);
	((ABIFptr)fptr)(obj);
#else
	DE_UNREF(fptr);
	DE_UNREF(obj);
	TCU_THROW(NotSupportedError, "ABI not supported");
#endif
}

template<typename T1, typename T2>
T1* pointerToOffset (T2* ptr, size_t bytes)
{
	return reinterpret_cast<T1*>((deUint8*)ptr + bytes);
}

static android::android_native_base_t* getAndroidNativeBase (android::GraphicBuffer* gb)
{
	// \note: assuming Itanium ABI
	return pointerToOffset<android::android_native_base_t>(gb, 2 * DE_PTR_SIZE);
}

//! android_native_base_t::magic for ANativeWindowBuffer
static deInt32 getExpectedNativeBufferVersion (void)
{
#if (DE_PTR_SIZE == 4)
	return 96;
#elif (DE_PTR_SIZE == 8)
	return 168;
#else
#	error Invalid DE_PTR_SIZE
#endif
}

//! access android_native_base_t::magic
static deUint32 getNativeBaseMagic (android::android_native_base_t* base)
{
	return *pointerToOffset<deUint32>(base, 0);
}

//! access android_native_base_t::version
static deUint32 getNativeBaseVersion (android::android_native_base_t* base)
{
	return *pointerToOffset<deInt32>(base, 4);
}

//! access android_native_base_t::incRef
static NativeBaseFunctions::incRefFunc getNativeBaseIncRefFunc (android::android_native_base_t* base)
{
	return *pointerToOffset<NativeBaseFunctions::incRefFunc>(base, 8 + DE_PTR_SIZE*4);
}

//! access android_native_base_t::decRef
static NativeBaseFunctions::decRefFunc getNativeBaseDecRefFunc (android::android_native_base_t* base)
{
	return *pointerToOffset<NativeBaseFunctions::decRefFunc>(base, 8 + DE_PTR_SIZE*5);
}

static android::GraphicBuffer* createGraphicBuffer (const GraphicBufferFunctions& functions, NativeBaseFunctions& baseFunctions, deUint32 w, deUint32 h, PixelFormat format, deUint32 usage)
{
	// \note: Hopefully uses the same allocator as libui
	void* const memory = deMalloc(GRAPHICBUFFER_SIZE);
	if (memory == DE_NULL)
		TCU_THROW(ResourceError, "Could not alloc for GraphicBuffer");
	else
	{
		try
		{
			android::GraphicBuffer* const			gb			= callConstructor4<android::GraphicBuffer, deUint32, deUint32, PixelFormat, deUint32>(functions.constructor,
																																					  memory,
																																					  GRAPHICBUFFER_SIZE,
																																					  w,
																																					  h,
																																					  format,
																																					  usage);
			android::android_native_base_t* const	base		= getAndroidNativeBase(gb);
			status_t								ctorStatus	= functions.initCheck(gb);

			if (ctorStatus)
			{
				// ctor failed
				callDestructor<android::GraphicBuffer>(functions.destructor, gb);
				TCU_THROW(NotSupportedError, ("GraphicBuffer ctor failed, initCheck returned " + de::toString(ctorStatus)).c_str());
			}

			// check object layout
			{
				const deUint32 magic		= getNativeBaseMagic(base);
				const deUint32 bufferMagic	= 0x5f626672u; // "_bfr"

				if (magic != bufferMagic)
					TCU_THROW(NotSupportedError, "GraphicBuffer layout unexpected");
			}

			// check object version
			{
				const deInt32 version			= getNativeBaseVersion(base);
				const deInt32 expectedVersion	= getExpectedNativeBufferVersion();

				if (version != expectedVersion)
					TCU_THROW(NotSupportedError, "GraphicBuffer version unexpected");
			}

			// locate refcounting functions

			if (!baseFunctions.incRef || !baseFunctions.decRef)
			{
				baseFunctions.incRef = getNativeBaseIncRefFunc(base);
				baseFunctions.decRef = getNativeBaseDecRefFunc(base);
			}

			// take the initial reference and return
			baseFunctions.incRef(base);
			return gb;
		}
		catch (...)
		{
			deFree(memory);
			throw;
		}
	}
}

GraphicBuffer::GraphicBuffer (const LibUI& lib, deUint32 width, deUint32 height, PixelFormat format, deUint32 usage)
	: m_functions	(lib.getFunctions().graphicBuffer)
	, m_impl		(DE_NULL)
{
	m_baseFunctions.incRef = DE_NULL;
	m_baseFunctions.decRef = DE_NULL;

	// \note createGraphicBuffer updates m_baseFunctions
	m_impl = createGraphicBuffer(m_functions, m_baseFunctions, width, height, format, usage);
}

GraphicBuffer::~GraphicBuffer (void)
{
	if (m_impl && m_baseFunctions.decRef)
	{
		m_baseFunctions.decRef(getAndroidNativeBase(m_impl));
		m_impl = DE_NULL;
	}
}

status_t GraphicBuffer::lock (deUint32 usage, void** vaddr)
{
	return m_functions.lock(m_impl, usage, vaddr);
}

status_t GraphicBuffer::unlock (void)
{
	return m_functions.unlock(m_impl);
}

ANativeWindowBuffer* GraphicBuffer::getNativeBuffer (void) const
{
	return m_functions.getNativeBuffer(m_impl);
}

} // internal
} // Android
} // tcu
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ChannelRequest>

#include "TelepathyQt4/_gen/cli-channel-request-body.hpp"
#include "TelepathyQt4/_gen/cli-channel-request.moc.hpp"
#include "TelepathyQt4/_gen/channel-request.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/Account>
#include <TelepathyQt4/PendingFailure>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/PendingVoid>

#include <QDateTime>

/**
 * \addtogroup clientsideproxies Client-side proxies
 *
 * Proxy objects representing remote service objects accessed via D-Bus.
 *
 * In addition to providing direct access to methods, signals and properties
 * exported by the remote objects, some of these proxies offer features like
 * automatic inspection of remote object capabilities, property tracking,
 * backwards compatibility helpers for older services and other utilities.
 */

/**
 * \defgroup clientchannelrequest ChannelRequest proxies
 * \ingroup clientsideproxies
 *
 * Proxy objects representing remote Telepathy Channel Requests and their
 * optional interfaces.
 */

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT ChannelRequest::Private
{
    Private(ChannelRequest *parent);
    ~Private();

    static void introspectMain(Private *self);

    void extractMainProps(const QVariantMap &props);

    // Public object
    ChannelRequest *parent;

    // Instance of generated interface class
    Client::ChannelRequestInterface *baseInterface;

    // Optional interface proxies
    Client::DBus::PropertiesInterface *properties;

    ReadinessHelper *readinessHelper;

    // Introspection
    AccountPtr account;
    QDateTime userActionTime;
    QString preferredHandler;
    QualifiedPropertyValueMapList requests;
};

ChannelRequest::Private::Private(ChannelRequest *parent)
    : parent(parent),
      baseInterface(new Client::ChannelRequestInterface(
                    parent->dbusConnection(), parent->busName(),
                    parent->objectPath(), parent)),
      properties(0),
      readinessHelper(parent->readinessHelper())
{
    debug() << "Creating new ChannelRequest:" << parent->objectPath();

    parent->connect(baseInterface,
            SIGNAL(Failed(const QString &, const QString &)),
            SIGNAL(failed(const QString &, const QString &)));
    parent->connect(baseInterface,
            SIGNAL(Succeeded()),
            SIGNAL(succeeded()));

    ReadinessHelper::Introspectables introspectables;

    // As ChannelRequest does not have predefined statuses let's simulate one (0)
    ReadinessHelper::Introspectable introspectableCore(
        QSet<uint>() << 0,                                           // makesSenseForStatuses
        Features(),                                                  // dependsOnFeatures
        QStringList(),                                               // dependsOnInterfaces
        (ReadinessHelper::IntrospectFunc) &Private::introspectMain,
        this);
    introspectables[FeatureCore] = introspectableCore;

    readinessHelper->addIntrospectables(introspectables);
}

ChannelRequest::Private::~Private()
{
}

void ChannelRequest::Private::introspectMain(ChannelRequest::Private *self)
{
    if (!self->properties) {
        self->properties = self->parent->propertiesInterface();
        Q_ASSERT(self->properties != 0);
    }

    debug() << "Calling Properties::GetAll(ChannelRequest)";
    QDBusPendingCallWatcher *watcher =
        new QDBusPendingCallWatcher(
                self->properties->GetAll(QLatin1String(TELEPATHY_INTERFACE_CHANNEL_REQUEST)),
                self->parent);
    // FIXME: This is a Qt bug fixed upstream, should be in the next Qt release.
    //        We should not need to check watcher->isFinished() here, remove the
    //        check when a fixed Qt version is released.
    if (watcher->isFinished()) {
        self->parent->gotMainProperties(watcher);
    } else {
        self->parent->connect(watcher,
                SIGNAL(finished(QDBusPendingCallWatcher*)),
                SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
    }
}

void ChannelRequest::Private::extractMainProps(const QVariantMap &props)
{
    parent->setInterfaces(qdbus_cast<QStringList>(props.value(QLatin1String("Interfaces"))));

    if (!account && props.contains(QLatin1String("Account"))) {
        QDBusObjectPath accountObjectPath =
            qdbus_cast<QDBusObjectPath>(props.value(QLatin1String("Account")));
        account = Account::create(
                QLatin1String(TELEPATHY_ACCOUNT_MANAGER_BUS_NAME),
                accountObjectPath.path());
    }

    // FIXME See http://bugs.freedesktop.org/show_bug.cgi?id=21690
    uint stamp = (uint) qdbus_cast<qlonglong>(props.value(QLatin1String("UserActionTime")));
    if (stamp != 0) {
        userActionTime = QDateTime::fromTime_t(stamp);
    }

    preferredHandler = qdbus_cast<QString>(props.value(QLatin1String("PreferredHandler")));
    requests = qdbus_cast<QualifiedPropertyValueMapList>(props.value(QLatin1String("Requests")));
}

/**
 * \class ChannelRequest
 * \ingroup clientchannelrequest
 * \headerfile <TelepathyQt4/channel-request.h> <TelepathyQt4/ChannelRequest>
 *
 * High-level proxy object for accessing remote Telepathy ChannelRequest objects.
 */

const Feature ChannelRequest::FeatureCore = Feature(QLatin1String(ChannelRequest::staticMetaObject.className()), 0, true);

ChannelRequestPtr ChannelRequest::create(const QString &objectPath,
        const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(QDBusConnection::sessionBus(),
                objectPath, immutableProperties));
}

ChannelRequestPtr ChannelRequest::create(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(bus, objectPath,
                immutableProperties));
}

ChannelRequest::ChannelRequest(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
    : StatefulDBusProxy(bus,
            QLatin1String(TELEPATHY_INTERFACE_CHANNEL_DISPATCHER),
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    mPriv->extractMainProps(immutableProperties);
}

/**
 * Class destructor.
 */
ChannelRequest::~ChannelRequest()
{
    delete mPriv;
}

AccountPtr ChannelRequest::account() const
{
    return mPriv->account;
}

QDateTime ChannelRequest::userActionTime() const
{
    return mPriv->userActionTime;
}

QString ChannelRequest::preferredHandler() const
{
    return mPriv->preferredHandler;
}

QualifiedPropertyValueMapList ChannelRequest::requests() const
{
    return mPriv->requests;
}

PendingOperation *ChannelRequest::cancel()
{
    return new PendingVoid(mPriv->baseInterface->Cancel(), this);
}

PendingOperation *ChannelRequest::proceed()
{
    return new PendingVoid(mPriv->baseInterface->Proceed(), this);
}

/**
 * Get the ChannelRequestInterface for this ChannelRequest class. This method is
 * protected since the convenience methods provided by this class should
 * always be used instead of the interface by users of the class.
 *
 * \return A pointer to the existing ChannelRequestInterface for this
 *         ChannelRequest
 */
Client::ChannelRequestInterface *ChannelRequest::baseInterface() const
{
    return mPriv->baseInterface;
}

void ChannelRequest::gotMainProperties(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QVariantMap> reply = *watcher;
    QVariantMap props;

    if (!reply.isError()) {
        debug() << "Got reply to Properties::GetAll(ChannelRequest)";
        props = reply.value();

        mPriv->extractMainProps(props);

        if (mPriv->account) {
            connect(mPriv->account->becomeReady(),
                    SIGNAL(finished(Tp::PendingOperation *)),
                    SLOT(onAccountReady(Tp::PendingOperation *)));
        } else {
            warning() << "Properties.GetAll(ChannelRequest) is missing "
                "account property, ignoring";
            mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
        }
    }
    else {
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore,
                false, reply.error());
        warning().nospace() << "Properties::GetAll(ChannelRequest) failed with "
            << reply.error().name() << ": " << reply.error().message();
    }
}

void ChannelRequest::onAccountReady(PendingOperation *op)
{
    if (op->isError()) {
        warning() << "Unable to make account ready";
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false,
                op->errorName(), op->errorMessage());
        return;
    }
    mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
}

} // Tp
<commit_msg>channel-request: Improve documentation (bugfixes+additions)<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2009 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2009 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/ChannelRequest>

#include "TelepathyQt4/_gen/cli-channel-request-body.hpp"
#include "TelepathyQt4/_gen/cli-channel-request.moc.hpp"
#include "TelepathyQt4/_gen/channel-request.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/Account>
#include <TelepathyQt4/PendingFailure>
#include <TelepathyQt4/PendingReady>
#include <TelepathyQt4/PendingVoid>

#include <QDateTime>

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT ChannelRequest::Private
{
    Private(ChannelRequest *parent);
    ~Private();

    static void introspectMain(Private *self);

    void extractMainProps(const QVariantMap &props);

    // Public object
    ChannelRequest *parent;

    // Instance of generated interface class
    Client::ChannelRequestInterface *baseInterface;

    // Optional interface proxies
    Client::DBus::PropertiesInterface *properties;

    ReadinessHelper *readinessHelper;

    // Introspection
    AccountPtr account;
    QDateTime userActionTime;
    QString preferredHandler;
    QualifiedPropertyValueMapList requests;
};

ChannelRequest::Private::Private(ChannelRequest *parent)
    : parent(parent),
      baseInterface(new Client::ChannelRequestInterface(
                    parent->dbusConnection(), parent->busName(),
                    parent->objectPath(), parent)),
      properties(0),
      readinessHelper(parent->readinessHelper())
{
    debug() << "Creating new ChannelRequest:" << parent->objectPath();

    parent->connect(baseInterface,
            SIGNAL(Failed(const QString &, const QString &)),
            SIGNAL(failed(const QString &, const QString &)));
    parent->connect(baseInterface,
            SIGNAL(Succeeded()),
            SIGNAL(succeeded()));

    ReadinessHelper::Introspectables introspectables;

    // As ChannelRequest does not have predefined statuses let's simulate one (0)
    ReadinessHelper::Introspectable introspectableCore(
        QSet<uint>() << 0,                                           // makesSenseForStatuses
        Features(),                                                  // dependsOnFeatures
        QStringList(),                                               // dependsOnInterfaces
        (ReadinessHelper::IntrospectFunc) &Private::introspectMain,
        this);
    introspectables[FeatureCore] = introspectableCore;

    readinessHelper->addIntrospectables(introspectables);
}

ChannelRequest::Private::~Private()
{
}

void ChannelRequest::Private::introspectMain(ChannelRequest::Private *self)
{
    if (!self->properties) {
        self->properties = self->parent->propertiesInterface();
        Q_ASSERT(self->properties != 0);
    }

    debug() << "Calling Properties::GetAll(ChannelRequest)";
    QDBusPendingCallWatcher *watcher =
        new QDBusPendingCallWatcher(
                self->properties->GetAll(QLatin1String(TELEPATHY_INTERFACE_CHANNEL_REQUEST)),
                self->parent);
    // FIXME: This is a Qt bug fixed upstream, should be in the next Qt release.
    //        We should not need to check watcher->isFinished() here, remove the
    //        check when a fixed Qt version is released.
    if (watcher->isFinished()) {
        self->parent->gotMainProperties(watcher);
    } else {
        self->parent->connect(watcher,
                SIGNAL(finished(QDBusPendingCallWatcher*)),
                SLOT(gotMainProperties(QDBusPendingCallWatcher*)));
    }
}

void ChannelRequest::Private::extractMainProps(const QVariantMap &props)
{
    parent->setInterfaces(qdbus_cast<QStringList>(props.value(QLatin1String("Interfaces"))));

    if (!account && props.contains(QLatin1String("Account"))) {
        QDBusObjectPath accountObjectPath =
            qdbus_cast<QDBusObjectPath>(props.value(QLatin1String("Account")));
        account = Account::create(
                QLatin1String(TELEPATHY_ACCOUNT_MANAGER_BUS_NAME),
                accountObjectPath.path());
    }

    // FIXME See http://bugs.freedesktop.org/show_bug.cgi?id=21690
    uint stamp = (uint) qdbus_cast<qlonglong>(props.value(QLatin1String("UserActionTime")));
    if (stamp != 0) {
        userActionTime = QDateTime::fromTime_t(stamp);
    }

    preferredHandler = qdbus_cast<QString>(props.value(QLatin1String("PreferredHandler")));
    requests = qdbus_cast<QualifiedPropertyValueMapList>(props.value(QLatin1String("Requests")));
}

/**
 * \class ChannelRequest
 * \ingroup clientchannelrequest
 * \headerfile TelepathyQt4/channel-request.h <TelepathyQt4/ChannelRequest>
 *
 * \brief The ChannelRequest class provides an object representing a Telepathy
 * channel request.
 *
 * A channel request is an object in the channel dispatcher representing an
 * ongoing request for some channels to be created or found. There can be any
 * number of channel request objects at the same time.
 *
 * A channel request can be cancelled by any client (not just the one that
 * requested it). This means that the channel dispatcher will close the
 * resulting channel, or refrain from requesting it at all, rather than
 * dispatching it to a handler.
 */

/**
 * Feature representing the core that needs to become ready to make the
 * ChannelRequest object usable.
 *
 * Note that this feature must be enabled in order to use most
 * ChannelRequest methods.
 *
 * When calling isReady(), becomeReady(), this feature is implicitly added
 * to the requested features.
 */
const Feature ChannelRequest::FeatureCore = Feature(QLatin1String(ChannelRequest::staticMetaObject.className()), 0, true);

/**
 * Create a new channel request object using QDBusConnection::sessionBus().
 *
 * \param objectPath The channel request object path.
 * \param immutableProperties The immutable properties of the channel request.
 * \return A ChannelRequestPtr pointing to the newly created ChannelRequest.
 */
ChannelRequestPtr ChannelRequest::create(const QString &objectPath,
        const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(QDBusConnection::sessionBus(),
                objectPath, immutableProperties));
}

/**
 * Create a new channel request object using the given \a bus.
 *
 * \param bus QDBusConnection to use.
 * \param objectPath The channel request object path.
 * \param immutableProperties The immutable properties of the channel request.
 * \return A ChannelRequestPtr pointing to the newly created ChannelRequest.
 */
ChannelRequestPtr ChannelRequest::create(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
{
    return ChannelRequestPtr(new ChannelRequest(bus, objectPath,
                immutableProperties));
}

/**
 * Construct a new channel request object using the given \a bus.
 *
 * \param bus QDBusConnection to use.
 * \param objectPath The channel request object path.
 * \param immutableProperties The immutable properties of the channel request.
 * \return A ChannelRequestPtr pointing to the newly created ChannelRequest.
 */
ChannelRequest::ChannelRequest(const QDBusConnection &bus,
        const QString &objectPath, const QVariantMap &immutableProperties)
    : StatefulDBusProxy(bus,
            QLatin1String(TELEPATHY_INTERFACE_CHANNEL_DISPATCHER),
            objectPath),
      OptionalInterfaceFactory<ChannelRequest>(this),
      ReadyObject(this, FeatureCore),
      mPriv(new Private(this))
{
    mPriv->extractMainProps(immutableProperties);
}

/**
 * Class destructor.
 */
ChannelRequest::~ChannelRequest()
{
    delete mPriv;
}

/**
 * Return the Account on which this request was made.
 *
 * This method requires ChannelRequest::FeatureCore to be enabled.
 *
 * \return The account on which this request was made.
 */
AccountPtr ChannelRequest::account() const
{
    return mPriv->account;
}

/**
 * Return the time at which the user action occurred, or 0 if this channel
 * request is for some reason not involving user action.
 *
 * Unix developers: this corresponds to the _NET_WM_USER_TIME property in EWMH.
 *
 * This property is set when the channel request is created, and can never
 * change.
 *
 * This method requires ChannelRequest::FeatureCore to be enabled.
 *
 * \return The time at which the user action occurred.
 */
QDateTime ChannelRequest::userActionTime() const
{
    return mPriv->userActionTime;
}

/**
 * Return either the well-known bus name (starting with
 * org.freedesktop.Telepathy.Client.) of the preferred handler for this channel,
 * or an empty string to indicate that any handler would be acceptable.
 *
 * This property is set when the channel request is created, and can never
 * change.
 *
 * This method requires ChannelRequest::FeatureCore to be enabled.
 *
 * \return The preferred handler or an empty string if any handler would be
 *         acceptable.
 */
QString ChannelRequest::preferredHandler() const
{
    return mPriv->preferredHandler;
}

/**
 * Return the desirable properties for the channel or channels to be created.
 *
 * This property is set when the channel request is created, and can never
 * change.
 *
 * This method requires ChannelRequest::FeatureCore to be enabled.
 *
 * \return The preferred handler or an empty string if any handler would be
 *         acceptable.
 */
QualifiedPropertyValueMapList ChannelRequest::requests() const
{
    return mPriv->requests;
}

/**
 * Cancel the channel request.
 *
 * If failed() is emitted in response to this method, the error will be
 * #TELEPATHY_ERROR_CANCELLED.
 *
 * If the channel has already been dispatched to a handler, then it's too late
 * to call this method, and the channel request will no longer exist.
 *
 * \return A PendingOperation which will emit PendingOperation::finished
 *         when the call has finished.
 */
PendingOperation *ChannelRequest::cancel()
{
    return new PendingVoid(mPriv->baseInterface->Cancel(), this);
}

/**
 * Proceed with the channel request.
 *
 * The client that created this object calls this method when it has connected
 * signal handlers for succeeded() and failed(). Note that this is done
 * automatically when using PendingChannelRequest.
 *
 * \return A PendingOperation which will emit PendingOperation::finished
 *         when the call has finished.
 */
PendingOperation *ChannelRequest::proceed()
{
    return new PendingVoid(mPriv->baseInterface->Proceed(), this);
}

/**
 * Return the ChannelRequestInterface for this ChannelRequest class. This method is
 * protected since the convenience methods provided by this class should
 * always be used instead of the interface by users of the class.
 *
 * \return A pointer to the existing ChannelRequestInterface for this
 *         ChannelRequest
 */
Client::ChannelRequestInterface *ChannelRequest::baseInterface() const
{
    return mPriv->baseInterface;
}

/**
 * \fn void ChannelRequest::failed(const QString &errorName,
 *             const QString &errorMessage);
 *
 * This signal is emitted when the channel request has failed. No further
 * methods must not be called on it.
 *
 * \param errorName The name of a D-Bus error.
 * \param errorMessage The error message.
 */

/**
 * \fn void ChannelRequest::succeeded();
 *
 * This signals is emitted when the channel request has succeeded. No further
 * methods must not be called on it.
 */

/**
 * \fn Client::DBus::PropertiesInterface *ChannelRequest::propertiesInterface() const
 *
 * Convenience function for getting a PropertiesInterface interface proxy object
 * for this account. The ChannelRequest interface relies on
 * properties, so this interface is always assumed to be present.
 *
 * \return A pointer to the existing Client::DBus::PropertiesInterface object
 *         for this ChannelRequest object.
 */

void ChannelRequest::gotMainProperties(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QVariantMap> reply = *watcher;
    QVariantMap props;

    if (!reply.isError()) {
        debug() << "Got reply to Properties::GetAll(ChannelRequest)";
        props = reply.value();

        mPriv->extractMainProps(props);

        if (mPriv->account) {
            connect(mPriv->account->becomeReady(),
                    SIGNAL(finished(Tp::PendingOperation *)),
                    SLOT(onAccountReady(Tp::PendingOperation *)));
        } else {
            warning() << "Properties.GetAll(ChannelRequest) is missing "
                "account property, ignoring";
            mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
        }
    }
    else {
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore,
                false, reply.error());
        warning().nospace() << "Properties::GetAll(ChannelRequest) failed with "
            << reply.error().name() << ": " << reply.error().message();
    }
}

void ChannelRequest::onAccountReady(PendingOperation *op)
{
    if (op->isError()) {
        warning() << "Unable to make account ready";
        mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, false,
                op->errorName(), op->errorMessage());
        return;
    }
    mPriv->readinessHelper->setIntrospectCompleted(FeatureCore, true);
}

} // Tp
<|endoftext|>


<commit_before>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2008 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/PendingAccount>

#include "TelepathyQt4/_gen/pending-account.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/AccountManager>

#include <QDBusObjectPath>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>

/**
 * \addtogroup clientsideproxies Client-side proxies
 *
 * Proxy objects representing remote service objects accessed via D-Bus.
 *
 * In addition to providing direct access to methods, signals and properties
 * exported by the remote objects, some of these proxies offer features like
 * automatic inspection of remote object capabilities, property tracking,
 * backwards compatibility helpers for older services and other utilities.
 */

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT PendingAccount::Private
{
    Private(const AccountManagerPtr &manager) :
        manager(manager)
    {
    }

    WeakPtr<AccountManager> manager;
    AccountPtr account;
    QDBusObjectPath objectPath;
};

/**
 * \class PendingAccount
 * \ingroup clientaccount
 * \headerfile <TelepathyQt4/pending-account.h> <TelepathyQt4/PendingAccount>
 *
 * Class containing the parameters of and the reply to an asynchronous account
 * request. Instances of this class cannot be constructed directly; the only
 * way to get one is via AccountManager.
 */

/**
 * Construct a PendingAccount object.
 *
 * \param manager AccountManager to use.
 * \param connectionManager Name of the connection manager to create the account for.
 * \param protocol Name of the protocol to create the account for.
 * \param displayName Account display name.
 * \param parameters Account parameters.
 */
PendingAccount::PendingAccount(const AccountManagerPtr &manager,
        const QString &connectionManager, const QString &protocol,
        const QString &displayName, const QVariantMap &parameters,
        const QVariantMap &properties)
    : PendingOperation(manager.data()),
      mPriv(new Private(manager))
{
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
            manager->baseInterface()->CreateAccount(connectionManager,
                protocol, displayName, parameters, properties), this);
    connect(watcher,
            SIGNAL(finished(QDBusPendingCallWatcher *)),
            SLOT(onCallFinished(QDBusPendingCallWatcher *)));
}

/**
 * Class destructor.
 */
PendingAccount::~PendingAccount()
{
    delete mPriv;
}

/**
 * Return the AccountManager object through which the request was made.
 *
 * \return Account Manager object.
 */
AccountManagerPtr PendingAccount::manager() const
{
    return AccountManagerPtr(mPriv->manager);
}

/**
 * Returns the newly created Account object.
 *
 * \return Account object.
 */
AccountPtr PendingAccount::account() const
{
    if (!isFinished()) {
        warning() << "PendingAccount::account called before finished, returning 0";
        return AccountPtr();
    } else if (!isValid()) {
        warning() << "PendingAccount::account called when not valid, returning 0";
        return AccountPtr();
    }

    if (!mPriv->account) {
        AccountManagerPtr manager(mPriv->manager);
        mPriv->account = Account::create(manager->dbusConnection(),
                manager->busName(), mPriv->objectPath.path());
    }

    return mPriv->account;
}

/**
 * Returns the account object path or an empty string on error.
 *
 * This method is useful for creating custom Account objects, so instead of using
 * PendingAccount::account, one could construct a new custom account with
 * the object path.
 *
 * \return Account object path.
 */
QString PendingAccount::objectPath() const
{
    if (!isFinished()) {
        warning() << "PendingAccount::account called before finished";
    } else if (!isValid()) {
        warning() << "PendingAccount::account called when not valid";
    }

    return mPriv->objectPath.path();
}

void PendingAccount::onCallFinished(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QDBusObjectPath> reply = *watcher;

    if (!reply.isError()) {
        mPriv->objectPath = reply.value();
        debug() << "Got reply to AccountManager.CreateAccount - object path:" <<
            mPriv->objectPath.path();
        setFinished();
    } else {
        debug().nospace() <<
            "CreateAccount failed: " <<
            reply.error().name() << ": " << reply.error().message();
        setFinishedWithError(reply.error());
    }

    watcher->deleteLater();
}

} // Tp
<commit_msg>pending-account: Improve documentation (bugfixes+additions)<commit_after>/*
 * This file is part of TelepathyQt4
 *
 * Copyright (C) 2008 Collabora Ltd. <http://www.collabora.co.uk/>
 * Copyright (C) 2008 Nokia Corporation
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <TelepathyQt4/PendingAccount>

#include "TelepathyQt4/_gen/pending-account.moc.hpp"

#include "TelepathyQt4/debug-internal.h"

#include <TelepathyQt4/AccountManager>

#include <QDBusObjectPath>
#include <QDBusPendingCallWatcher>
#include <QDBusPendingReply>

namespace Tp
{

struct TELEPATHY_QT4_NO_EXPORT PendingAccount::Private
{
    Private(const AccountManagerPtr &manager) :
        manager(manager)
    {
    }

    WeakPtr<AccountManager> manager;
    AccountPtr account;
    QDBusObjectPath objectPath;
};

/**
 * \class PendingAccount
 * \ingroup clientaccount
 * \headerfile TelepathyQt4/pending-account.h <TelepathyQt4/PendingAccount>
 *
 * \brief Class containing the parameters of and the reply to an asynchronous
 * account request.
 *
 * Instances of this class cannot be constructed directly; the only way to get
 * one is via AccountManager.
 *
 * See \ref async_model
 */

/**
 * Construct a new PendingAccount object.
 *
 * \param manager AccountManager to use.
 * \param connectionManager Name of the connection manager to create the account
 *                          for.
 * \param protocol Name of the protocol to create the account for.
 * \param displayName Account display name.
 * \param parameters Account parameters.
 * \param properties An optional map from fully qualified D-Bus property
 *                   names such as "org.freedesktop.Telepathy.Account.Enabled"
 *                   to their values.
 */
PendingAccount::PendingAccount(const AccountManagerPtr &manager,
        const QString &connectionManager, const QString &protocol,
        const QString &displayName, const QVariantMap &parameters,
        const QVariantMap &properties)
    : PendingOperation(manager.data()),
      mPriv(new Private(manager))
{
    QDBusPendingCallWatcher *watcher = new QDBusPendingCallWatcher(
            manager->baseInterface()->CreateAccount(connectionManager,
                protocol, displayName, parameters, properties), this);
    connect(watcher,
            SIGNAL(finished(QDBusPendingCallWatcher *)),
            SLOT(onCallFinished(QDBusPendingCallWatcher *)));
}

/**
 * Class destructor.
 */
PendingAccount::~PendingAccount()
{
    delete mPriv;
}

/**
 * Return the AccountManagerPtr object through which the request was made.
 *
 * \return An AccountManagerPtr object.
 */
AccountManagerPtr PendingAccount::manager() const
{
    return AccountManagerPtr(mPriv->manager);
}

/**
 * Returns the newly created AccountPtr object.
 *
 * \return An AccountPtr object pointing to the newly create Account object, or
 *         a null AccountPtr if an error occurred.
 * \sa objectPath()
 */
AccountPtr PendingAccount::account() const
{
    if (!isFinished()) {
        warning() << "PendingAccount::account called before finished, returning 0";
        return AccountPtr();
    } else if (!isValid()) {
        warning() << "PendingAccount::account called when not valid, returning 0";
        return AccountPtr();
    }

    if (!mPriv->account) {
        AccountManagerPtr manager(mPriv->manager);
        mPriv->account = Account::create(manager->dbusConnection(),
                manager->busName(), mPriv->objectPath.path());
    }

    return mPriv->account;
}

/**
 * Returns the account object path.
 *
 * This method is useful for creating custom Account objects, so instead of
 * using PendingAccount::account, one could construct a new custom account with
 * the object path.
 *
 * \return Account object path or an empty string an error occurred.
 */
QString PendingAccount::objectPath() const
{
    if (!isFinished()) {
        warning() << "PendingAccount::account called before finished";
    } else if (!isValid()) {
        warning() << "PendingAccount::account called when not valid";
    }

    return mPriv->objectPath.path();
}

void PendingAccount::onCallFinished(QDBusPendingCallWatcher *watcher)
{
    QDBusPendingReply<QDBusObjectPath> reply = *watcher;

    if (!reply.isError()) {
        mPriv->objectPath = reply.value();
        debug() << "Got reply to AccountManager.CreateAccount - object path:" <<
            mPriv->objectPath.path();
        setFinished();
    } else {
        debug().nospace() <<
            "CreateAccount failed: " <<
            reply.error().name() << ": " << reply.error().message();
        setFinishedWithError(reply.error());
    }

    watcher->deleteLater();
}

} // Tp
<|endoftext|>


<commit_before>#include <StdAfx.h>
#include <UI/Dialogs/Editors/HexEditor.h>
#include <UI/FileDialogEx.h>
#include <UI/ViewPane/CountedTextPane.h>
#include <UI/ViewPane/SmartViewPane.h>
#include <UI/ViewPane/SplitterPane.h>
#include <MAPI/Cache/GlobalCache.h>
#include <MAPI/MAPIFunctions.h>

namespace dialog
{
	namespace editor
	{
		static std::wstring CLASS = L"CHexEditor";

		enum __HexEditorFields
		{
			HEXED_TEXT,
			HEXED_ANSI,
			HEXED_UNICODE,
			HEXED_BASE64,
			HEXED_HEX,
			HEXED_SMARTVIEW
		};

		CHexEditor::CHexEditor(_In_ ui::CParentWnd* pParentWnd, _In_ cache::CMapiObjects* lpMapiObjects)
			: CEditor(
				  pParentWnd,
				  IDS_HEXEDITOR,
				  NULL,
				  CEDITOR_BUTTON_ACTION1 | CEDITOR_BUTTON_ACTION2 | CEDITOR_BUTTON_ACTION3,
				  IDS_IMPORT,
				  IDS_EXPORT,
				  IDS_CLOSE)
		{
			TRACE_CONSTRUCTOR(CLASS);
			m_lpMapiObjects = lpMapiObjects;
			if (m_lpMapiObjects) m_lpMapiObjects->AddRef();

			auto splitter = viewpane::SplitterPane::CreateHorizontalPane(HEXED_TEXT, IDS_TEXT);
			AddPane(splitter);
			splitter->SetPaneOne(viewpane::TextPane::CreateCollapsibleTextPane(HEXED_ANSI, IDS_ANSISTRING, false));
			splitter->SetPaneTwo(viewpane::TextPane::CreateMultiLinePane(HEXED_UNICODE, NULL, false));
			AddPane(viewpane::CountedTextPane::Create(HEXED_BASE64, IDS_BASE64STRING, false, IDS_CCH));
			AddPane(viewpane::CountedTextPane::Create(HEXED_HEX, IDS_HEX, false, IDS_CB));
			AddPane(viewpane::SmartViewPane::Create(HEXED_SMARTVIEW, IDS_SMARTVIEW));
			DisplayParentedDialog(pParentWnd, 1000);
		}

		CHexEditor::~CHexEditor()
		{
			TRACE_DESTRUCTOR(CLASS);

			if (m_lpMapiObjects) m_lpMapiObjects->Release();
		}

		void CHexEditor::OnOK()
		{
			ShowWindow(SW_HIDE);
			delete this;
		}

		void CHexEditor::OnCancel() { OnOK(); }

		_Check_return_ ULONG CHexEditor::HandleChange(UINT nID)
		{
			const auto paneID = CEditor::HandleChange(nID);

			if (paneID == static_cast<ULONG>(-1)) return static_cast<ULONG>(-1);

			auto lpb = LPBYTE{};
			size_t cb = 0;
			std::wstring szEncodeStr;
			size_t cchEncodeStr = 0;
			switch (paneID)
			{
			case HEXED_ANSI:
			{
				auto text = GetStringA(HEXED_ANSI);
				SetStringA(HEXED_UNICODE, text);

				lpb = LPBYTE(text.c_str());
				cb = text.length() * sizeof(CHAR);

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_UNICODE: // Unicode string changed
			{
				auto text = GetStringW(HEXED_UNICODE);
				SetStringW(HEXED_ANSI, text);

				lpb = LPBYTE(text.c_str());
				cb = text.length() * sizeof(WCHAR);

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_BASE64: // base64 changed
			{
				auto szTmpString = GetStringW(HEXED_BASE64);

				// remove any whitespace before decoding
				szTmpString = strings::StripCRLF(szTmpString);

				cchEncodeStr = szTmpString.length();
				auto bin = strings::Base64Decode(szTmpString);
				lpb = bin.data();
				cb = bin.size();

				SetStringA(HEXED_ANSI, std::string(LPCSTR(lpb), cb));
				if (!(cb % 2)) // Set Unicode String
				{
					SetStringW(HEXED_UNICODE, std::wstring(LPWSTR(lpb), cb / sizeof(WCHAR)));
				}
				else
				{
					SetStringW(HEXED_UNICODE, L"");
				}

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_HEX: // binary changed
			{
				auto bin = GetBinary(HEXED_HEX);
				lpb = bin.data();
				cb = bin.size();
				SetStringA(HEXED_ANSI, std::string(LPCSTR(lpb), cb)); // ansi string

				if (!(cb % 2)) // Set Unicode String
				{
					SetStringW(HEXED_UNICODE, std::wstring(LPWSTR(lpb), cb / sizeof(WCHAR)));
				}
				else
				{
					SetStringW(HEXED_UNICODE, L"");
				}

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);
			}
			break;
			default:
				break;
			}

			if (HEXED_SMARTVIEW != paneID)
			{
				// length of base64 encoded string
				auto lpPane = dynamic_cast<viewpane::CountedTextPane*>(GetPane(HEXED_BASE64));
				if (lpPane)
				{
					lpPane->SetCount(cchEncodeStr);
				}

				lpPane = dynamic_cast<viewpane::CountedTextPane*>(GetPane(HEXED_HEX));
				if (lpPane)
				{
					lpPane->SetCount(cb);
				}
			}

			// Update any parsing we've got:
			UpdateParser();

			// Force the new layout
			OnRecalcLayout();

			return paneID;
		}

		void CHexEditor::UpdateParser() const
		{
			// Find out how to interpret the data
			auto lpPane = dynamic_cast<viewpane::SmartViewPane*>(GetPane(HEXED_SMARTVIEW));
			if (lpPane)
			{
				auto bin = GetBinary(HEXED_HEX);
				lpPane->Parse(SBinary{ULONG(bin.size()), bin.data()});
			}
		}

		// Import
		void CHexEditor::OnEditAction1()
		{
			auto file = file::CFileDialogExW::OpenFile(
				strings::emptystring, strings::emptystring, OFN_FILEMUSTEXIST, strings::loadstring(IDS_ALLFILES), this);
			if (!file.empty())
			{
				cache::CGlobalCache::getInstance().MAPIInitialize(NULL);
				LPSTREAM lpStream = nullptr;

				// Get a Stream interface on the input file
				EC_H_S(mapi::MyOpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_READ, file, &lpStream));

				if (lpStream)
				{
					auto lpPane = dynamic_cast<viewpane::TextPane*>(GetPane(HEXED_HEX));
					if (lpPane)
					{
						lpPane->SetBinaryStream(lpStream);
					}

					lpStream->Release();
				}
			}
		}

		// Export
		void CHexEditor::OnEditAction2()
		{
			auto file = file::CFileDialogExW::SaveAs(
				strings::emptystring,
				strings::emptystring,
				OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
				strings::loadstring(IDS_ALLFILES),
				this);
			if (!file.empty())
			{
				cache::CGlobalCache::getInstance().MAPIInitialize(NULL);
				LPSTREAM lpStream = nullptr;

				// Get a Stream interface on the output file
				EC_H_S(mapi::MyOpenStreamOnFile(
					MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, file, &lpStream));

				if (lpStream)
				{
					const auto lpPane = dynamic_cast<viewpane::TextPane*>(GetPane(HEXED_HEX));
					if (lpPane)
					{
						lpPane->GetBinaryStream(lpStream);
					}

					lpStream->Release();
				}
			}
		}

		// Close
		void CHexEditor::OnEditAction3() { OnOK(); }
	} // namespace editor
} // namespace dialog
<commit_msg>Remove hex edit text labels<commit_after>#include <StdAfx.h>
#include <UI/Dialogs/Editors/HexEditor.h>
#include <UI/FileDialogEx.h>
#include <UI/ViewPane/CountedTextPane.h>
#include <UI/ViewPane/SmartViewPane.h>
#include <UI/ViewPane/SplitterPane.h>
#include <MAPI/Cache/GlobalCache.h>
#include <MAPI/MAPIFunctions.h>

namespace dialog
{
	namespace editor
	{
		static std::wstring CLASS = L"CHexEditor";

		enum __HexEditorFields
		{
			HEXED_TEXT,
			HEXED_ANSI,
			HEXED_UNICODE,
			HEXED_BASE64,
			HEXED_HEX,
			HEXED_SMARTVIEW
		};

		CHexEditor::CHexEditor(_In_ ui::CParentWnd* pParentWnd, _In_ cache::CMapiObjects* lpMapiObjects)
			: CEditor(
				  pParentWnd,
				  IDS_HEXEDITOR,
				  NULL,
				  CEDITOR_BUTTON_ACTION1 | CEDITOR_BUTTON_ACTION2 | CEDITOR_BUTTON_ACTION3,
				  IDS_IMPORT,
				  IDS_EXPORT,
				  IDS_CLOSE)
		{
			TRACE_CONSTRUCTOR(CLASS);
			m_lpMapiObjects = lpMapiObjects;
			if (m_lpMapiObjects) m_lpMapiObjects->AddRef();

			auto splitter = viewpane::SplitterPane::CreateHorizontalPane(HEXED_TEXT, IDS_TEXT);
			AddPane(splitter);
			splitter->SetPaneOne(viewpane::TextPane::CreateMultiLinePane(HEXED_ANSI, NULL, false));
			splitter->SetPaneTwo(viewpane::TextPane::CreateMultiLinePane(HEXED_UNICODE, NULL, false));
			AddPane(viewpane::CountedTextPane::Create(HEXED_BASE64, IDS_BASE64STRING, false, IDS_CCH));
			AddPane(viewpane::CountedTextPane::Create(HEXED_HEX, IDS_HEX, false, IDS_CB));
			AddPane(viewpane::SmartViewPane::Create(HEXED_SMARTVIEW, IDS_SMARTVIEW));
			DisplayParentedDialog(pParentWnd, 1000);
		}

		CHexEditor::~CHexEditor()
		{
			TRACE_DESTRUCTOR(CLASS);

			if (m_lpMapiObjects) m_lpMapiObjects->Release();
		}

		void CHexEditor::OnOK()
		{
			ShowWindow(SW_HIDE);
			delete this;
		}

		void CHexEditor::OnCancel() { OnOK(); }

		_Check_return_ ULONG CHexEditor::HandleChange(UINT nID)
		{
			const auto paneID = CEditor::HandleChange(nID);

			if (paneID == static_cast<ULONG>(-1)) return static_cast<ULONG>(-1);

			auto lpb = LPBYTE{};
			size_t cb = 0;
			std::wstring szEncodeStr;
			size_t cchEncodeStr = 0;
			switch (paneID)
			{
			case HEXED_ANSI:
			{
				auto text = GetStringA(HEXED_ANSI);
				SetStringA(HEXED_UNICODE, text);

				lpb = LPBYTE(text.c_str());
				cb = text.length() * sizeof(CHAR);

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_UNICODE: // Unicode string changed
			{
				auto text = GetStringW(HEXED_UNICODE);
				SetStringW(HEXED_ANSI, text);

				lpb = LPBYTE(text.c_str());
				cb = text.length() * sizeof(WCHAR);

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_BASE64: // base64 changed
			{
				auto szTmpString = GetStringW(HEXED_BASE64);

				// remove any whitespace before decoding
				szTmpString = strings::StripCRLF(szTmpString);

				cchEncodeStr = szTmpString.length();
				auto bin = strings::Base64Decode(szTmpString);
				lpb = bin.data();
				cb = bin.size();

				SetStringA(HEXED_ANSI, std::string(LPCSTR(lpb), cb));
				if (!(cb % 2)) // Set Unicode String
				{
					SetStringW(HEXED_UNICODE, std::wstring(LPWSTR(lpb), cb / sizeof(WCHAR)));
				}
				else
				{
					SetStringW(HEXED_UNICODE, L"");
				}

				SetBinary(HEXED_HEX, lpb, cb);
			}
			break;
			case HEXED_HEX: // binary changed
			{
				auto bin = GetBinary(HEXED_HEX);
				lpb = bin.data();
				cb = bin.size();
				SetStringA(HEXED_ANSI, std::string(LPCSTR(lpb), cb)); // ansi string

				if (!(cb % 2)) // Set Unicode String
				{
					SetStringW(HEXED_UNICODE, std::wstring(LPWSTR(lpb), cb / sizeof(WCHAR)));
				}
				else
				{
					SetStringW(HEXED_UNICODE, L"");
				}

				szEncodeStr = strings::Base64Encode(cb, lpb);
				cchEncodeStr = szEncodeStr.length();
				SetStringW(HEXED_BASE64, szEncodeStr);
			}
			break;
			default:
				break;
			}

			if (HEXED_SMARTVIEW != paneID)
			{
				// length of base64 encoded string
				auto lpPane = dynamic_cast<viewpane::CountedTextPane*>(GetPane(HEXED_BASE64));
				if (lpPane)
				{
					lpPane->SetCount(cchEncodeStr);
				}

				lpPane = dynamic_cast<viewpane::CountedTextPane*>(GetPane(HEXED_HEX));
				if (lpPane)
				{
					lpPane->SetCount(cb);
				}
			}

			// Update any parsing we've got:
			UpdateParser();

			// Force the new layout
			OnRecalcLayout();

			return paneID;
		}

		void CHexEditor::UpdateParser() const
		{
			// Find out how to interpret the data
			auto lpPane = dynamic_cast<viewpane::SmartViewPane*>(GetPane(HEXED_SMARTVIEW));
			if (lpPane)
			{
				auto bin = GetBinary(HEXED_HEX);
				lpPane->Parse(SBinary{ULONG(bin.size()), bin.data()});
			}
		}

		// Import
		void CHexEditor::OnEditAction1()
		{
			auto file = file::CFileDialogExW::OpenFile(
				strings::emptystring, strings::emptystring, OFN_FILEMUSTEXIST, strings::loadstring(IDS_ALLFILES), this);
			if (!file.empty())
			{
				cache::CGlobalCache::getInstance().MAPIInitialize(NULL);
				LPSTREAM lpStream = nullptr;

				// Get a Stream interface on the input file
				EC_H_S(mapi::MyOpenStreamOnFile(MAPIAllocateBuffer, MAPIFreeBuffer, STGM_READ, file, &lpStream));

				if (lpStream)
				{
					auto lpPane = dynamic_cast<viewpane::TextPane*>(GetPane(HEXED_HEX));
					if (lpPane)
					{
						lpPane->SetBinaryStream(lpStream);
					}

					lpStream->Release();
				}
			}
		}

		// Export
		void CHexEditor::OnEditAction2()
		{
			auto file = file::CFileDialogExW::SaveAs(
				strings::emptystring,
				strings::emptystring,
				OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
				strings::loadstring(IDS_ALLFILES),
				this);
			if (!file.empty())
			{
				cache::CGlobalCache::getInstance().MAPIInitialize(NULL);
				LPSTREAM lpStream = nullptr;

				// Get a Stream interface on the output file
				EC_H_S(mapi::MyOpenStreamOnFile(
					MAPIAllocateBuffer, MAPIFreeBuffer, STGM_CREATE | STGM_READWRITE, file, &lpStream));

				if (lpStream)
				{
					const auto lpPane = dynamic_cast<viewpane::TextPane*>(GetPane(HEXED_HEX));
					if (lpPane)
					{
						lpPane->GetBinaryStream(lpStream);
					}

					lpStream->Release();
				}
			}
		}

		// Close
		void CHexEditor::OnEditAction3() { OnOK(); }
	} // namespace editor
} // namespace dialog
<|endoftext|>


<commit_before><commit_msg>10226 - Hardwood Species<commit_after><|endoftext|>


<commit_before>//
//  yas_processing_constant_module.cpp
//

#include "yas_processing_constant_signal_module.h"
#include "yas_processing_send_signal_processor.h"
#include "yas_processing_module.h"

using namespace yas;

template <typename T>
processing::module processing::constant::make_signal_module(T value) {
    auto processor = processing::make_send_signal_processor<T>([value = std::move(value)](
        processing::time_range const &time_range, channel_index_t const, std::string const &key, T *const signal_ptr) {
        auto idx = 0;
        auto const length = time_range.length;

        while (idx < length) {
            signal_ptr[idx] = value;
            ++idx;
        }
    });

    return processing::module{{std::move(processor)}};
}

template processing::module processing::constant::make_signal_module<double>(double);
template processing::module processing::constant::make_signal_module<float>(float);
template processing::module processing::constant::make_signal_module<int64_t>(int64_t);
template processing::module processing::constant::make_signal_module<int32_t>(int32_t);
template processing::module processing::constant::make_signal_module<int16_t>(int16_t);
template processing::module processing::constant::make_signal_module<int8_t>(int8_t);
template processing::module processing::constant::make_signal_module<uint64_t>(uint64_t);
template processing::module processing::constant::make_signal_module<uint32_t>(uint32_t);
template processing::module processing::constant::make_signal_module<uint16_t>(uint16_t);
template processing::module processing::constant::make_signal_module<uint8_t>(uint8_t);
<commit_msg>use ptr_enumerator<commit_after>//
//  yas_processing_constant_module.cpp
//

#include "yas_processing_constant_signal_module.h"
#include "yas_processing_send_signal_processor.h"
#include "yas_processing_module.h"
#include "yas_ptr_enumerator.h"

using namespace yas;

template <typename T>
processing::module processing::constant::make_signal_module(T value) {
    auto processor = processing::make_send_signal_processor<T>([value = std::move(value)](
        processing::time_range const &time_range, channel_index_t const, std::string const &key, T *const signal_ptr) {
        ptr_enumerator<T> ptr_enum{signal_ptr, time_range.length};

        while (yas_ptr_enumerator_has_value(ptr_enum)) {
            yas_ptr_enumerator_value(ptr_enum) = value;
            yas_ptr_enumerator_move(ptr_enum);
        }
    });

    return processing::module{{std::move(processor)}};
}

template processing::module processing::constant::make_signal_module<double>(double);
template processing::module processing::constant::make_signal_module<float>(float);
template processing::module processing::constant::make_signal_module<int64_t>(int64_t);
template processing::module processing::constant::make_signal_module<int32_t>(int32_t);
template processing::module processing::constant::make_signal_module<int16_t>(int16_t);
template processing::module processing::constant::make_signal_module<int8_t>(int8_t);
template processing::module processing::constant::make_signal_module<uint64_t>(uint64_t);
template processing::module processing::constant::make_signal_module<uint32_t>(uint32_t);
template processing::module processing::constant::make_signal_module<uint16_t>(uint16_t);
template processing::module processing::constant::make_signal_module<uint8_t>(uint8_t);
<|endoftext|>


<commit_before>// @(#)root/proofplayer:$Id$
// Author: Axel Naumann, 2010-06-09

/*************************************************************************
 * Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TOutputListSelectorDataMap
\ingroup proofkernel

Set the selector's data members to the corresponding elements of the
output list.

*/

#include "TOutputListSelectorDataMap.h"

#include "TClass.h"
#include "TDataMember.h"
#include "TExMap.h"
#include "THashTable.h"
#include "TList.h"
#include "TMemberInspector.h"
#include "TProofDebug.h"
#include "TSelector.h"
#include "TSelectorCint.h"

#include <cstddef>

namespace {

   static TClass* IsSettableDataMember(TDataMember* dm) {
      if (!dm || !dm->IsaPointer() || dm->IsBasic()) return 0;
      TString dtTypeName = dm->GetFullTypeName();
      if (!dtTypeName.EndsWith("*")) return 0;
      dtTypeName.Remove(dtTypeName.Length()-1);
      return TClass::GetClass(dtTypeName);
   }

   class TSetSelDataMembers: public TMemberInspector {
   public:
      TSetSelDataMembers(const TOutputListSelectorDataMap& owner, TCollection* dmInfo, TList* output);
      using TMemberInspector::Inspect;
      void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
      Ssiz_t GetNumSet() const { return fNumSet; }
   private:
      TCollection* fDMInfo; // output list object name / member name pairs for output list entries
      TList* fOutputList; // merged output list
      Ssiz_t fNumSet; // number of initialized data members
      const TOutputListSelectorDataMap& fOwner; // owner, used for messaging
   };
}

////////////////////////////////////////////////////////////////////////////////

TSetSelDataMembers::TSetSelDataMembers(const TOutputListSelectorDataMap& owner,
                                       TCollection* dmInfo, TList* output):
   fDMInfo(dmInfo), fOutputList(output), fNumSet(0), fOwner(owner)
{}

////////////////////////////////////////////////////////////////////////////////
/// This method is called by the ShowMembers() method for each
/// data member to recursively collect all base classes' members.
///
///    cl     is the pointer to the current class
///    parent is the parent name (in case of composed objects)
///    name   is the data member name
///    addr   is the data member address

void TSetSelDataMembers::Inspect(TClass *cl, const char* parent, const char *name, const void *addr, Bool_t /* isTransient */)
{
   while (name[0] == '*') ++name;

   TObject* mapping = fDMInfo->FindObject(name);
   if (!mapping) return;

   PDB(kOutput,1) fOwner.Info("SetDataMembers()",
                              "data member `%s%s::%s' maps to output list object `%s'",
                              cl->GetName(), parent, name, mapping->GetTitle());

   TObject* outputObj = fOutputList->FindObject(mapping->GetTitle());
   if (!outputObj) {
      PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
                                    "object `%s' not found in output list!",
                                    mapping->GetTitle());
      return;
   }

   // Check data member type
   TDataMember *dm = cl->GetDataMember(name);
   TClass* cldt = IsSettableDataMember(dm);
   if (!cldt) {
      PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
                                    "unusable data member `%s' should have been detected by TCollectDataMembers!",
                                    name);
      return;
   }

   char *pointer = (char*)addr;
   char **ppointer = (char**)(pointer);
   if (*ppointer) {
      // member points to something - replace instead of delete to not crash on deleting uninitialized values.
      fOwner.Warning("SetDataMembers()", "potential memory leak: replacing data member `%s' != 0. "
                     "Please initialize %s to 0 in constructor %s::%s()",
                     name, name, cl->GetName(), cl->GetName());
   }
   *ppointer = (char*)outputObj;
   ++fNumSet;
}

namespace {
   class TCollectDataMembers: public TMemberInspector {
   public:
      TCollectDataMembers(const TOutputListSelectorDataMap& owner): fOwner(owner) { }
      ~TCollectDataMembers();
      using TMemberInspector::Inspect;
      void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
      TExMap& GetMemberPointers() { return fMap; }
   private:
      TExMap fMap; //map of data member's value to TDataMember
      const TOutputListSelectorDataMap& fOwner; //owner, used for messaging
   };
}

////////////////////////////////////////////////////////////////////////////////
/// This method is called by the ShowMembers() method for each
/// data member to recursively collect all base classes' members.
///
///    cl     is the pointer to the current class
///    parent is the parent name (in case of composed objects)
///    name   is the data member name
///    addr   is the data member address

void TCollectDataMembers::Inspect(TClass *cl, const char* /*parent*/, const char *name, const void *addr, Bool_t /* isTransient */)
{
   TDataMember *dm = cl->GetDataMember(name);
   if (!IsSettableDataMember(dm)) return;

   char *pointer = (char*)addr;
   char **ppointer = (char**)(pointer);
   char **p3pointer = (char**)(*ppointer);
   if (p3pointer) {
      // The data member points to something.
      // Handle multiple pointers to the same output list object:
      TObject* prev = (TObject*) (ptrdiff_t)fMap.GetValue((Long64_t)(ptrdiff_t)p3pointer);
      if (prev) {
         // We have a previous entry - is it a data member or already a TList (of data members)?
         if (prev->InheritsFrom(TDataMember::Class())) {
            fMap.Remove((Long64_t)(ptrdiff_t)p3pointer);
            TList* dmList = new TList;
            dmList->Add(prev);
            dmList->Add(dm);
            fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dmList);
         } else {
            TList* prevList = (TList*) prev;
            prevList->Add(dm);
         }
      } else {
         fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dm);
      }
      if (name[0] == '*') ++name;
      PDB(kOutput,1) fOwner.Info("Init()", "considering data member `%s'", name);
   }
}

TCollectDataMembers::~TCollectDataMembers() {
   // Destructor

   // Clean up collection of TDataMembers in fMap
   TExMapIter iMembers(&fMap);
   Long64_t key;
   Long64_t value;
   while (iMembers.Next(key, value)) {
      TObject* obj = (TObject*) (ptrdiff_t) value;
      if (obj->InheritsFrom(TList::Class())) {
         delete obj;
      }
   }
}

ClassImp(TOutputListSelectorDataMap);

////////////////////////////////////////////////////////////////////////////////
/// Create a mapper between output list items and TSelector data members.

TOutputListSelectorDataMap::TOutputListSelectorDataMap(TSelector* sel /*= 0*/):
   fMap(0)
{
   if (sel) Init(sel);
}

////////////////////////////////////////////////////////////////////////////////
/// Return static name for TOutputListSelectorDataMap objects.

const char* TOutputListSelectorDataMap::GetName() const
{
   return "PROOF_TOutputListSelectorDataMap_object";
}

////////////////////////////////////////////////////////////////////////////////
/// Initialize the data member <-> output list mapping from a selector.

Bool_t TOutputListSelectorDataMap::Init(TSelector* sel)
{
   if (!sel) {
      PDB(kOutput,1) Warning("Init","Leave (no selector!)");
      return kFALSE;
   }
   TCollection* outList = sel->GetOutputList();
   if (!outList) {
      PDB(kOutput,1) Info("Init()","Leave (no output)");
      return kFALSE;
   }

   if (outList->FindObject(GetName())) {
      // mapping already exists?!
      PDB(kOutput,1) Warning("Init","Mapping already exists!");
      return kFALSE;
   }

   if (fMap) delete fMap;
   fMap = new THashTable;
   fMap->SetOwner();

   TCollectDataMembers cdm(*this);
   TClass* cl = sel->IsA();
   if (cl && cl->InheritsFrom(TSelectorCint::Class())) {
      // we don't want to set TSelectorCint's data members, but
      // the data members that it represents!
      TSelectorCint* selCINT = dynamic_cast<TSelectorCint*>(sel);
      if (selCINT) {
         cl = selCINT->GetInterpretedClass();
         sel = selCINT->GetInterpretedSelector();
      } else {
         cl = 0;
         Error("Init", "failed to get TSelectorCint interpreted class!");
      }
   }
   if (!cl || (cl && !cl->CallShowMembers(sel, cdm))) {
      // failed to map
      PDB(kOutput,1) Warning("Init","Failed to determine mapping!");
      return kFALSE;
   }
   PDB(kOutput,1) Info("Init()","Found %d data members.",
                        cdm.GetMemberPointers().GetSize());

   // Iterate over output list entries and find data members pointing to the
   // same value. Store that mapping (or a miss).
   TIter iOutput(outList);
   TObject* output;
   TList oneDM;
   while ((output = iOutput())) {
      TObject* obj = (TObject*) (ptrdiff_t)cdm.GetMemberPointers().GetValue((Long64_t)(ptrdiff_t)output);
      if (!obj) continue;

      TList* addAllDM = 0;
      if (obj->InheritsFrom(TDataMember::Class())) {
         oneDM.Add(obj);
         addAllDM = &oneDM;
      } else {
         addAllDM = (TList*) obj;
      }
      TIter iDM(addAllDM);
      TDataMember* dm = 0;
      while ((dm = (TDataMember*) iDM())) {
         fMap->Add(new TNamed(dm->GetName(), output->GetName()));
         PDB(kOutput,1) Info("Init()","Data member `%s' corresponds to output `%s'",
                              dm->GetName(), output->GetName());
      }
      oneDM.Clear();
   }

   return kTRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// Given an output list, set the data members of a TSelector.

Bool_t TOutputListSelectorDataMap::SetDataMembers(TSelector* sel) const
{
   TList* output = sel->GetOutputList();
   if (!output || output->IsEmpty()) return kTRUE;

   Bool_t res = kFALSE;
   // Set fSelector's data members
   TSetSelDataMembers ssdm(*this, fMap, output);
   TClass* cl = sel->IsA();
   if (cl) {
      if (cl->InheritsFrom(TSelectorCint::Class())) {
         // we don't want to set TSelectorCint's data members, but
         // the data members that it represents!
         TSelectorCint* selCINT = dynamic_cast<TSelectorCint*>(sel);
         if (selCINT) {
            cl = selCINT->GetInterpretedClass();
            sel = selCINT->GetInterpretedSelector();
         } else {
            cl = 0;
            Error("Init", "failed to get TSelectorCint interpreted class!");
            return kFALSE;
         }
      }
      res = cl->CallShowMembers(sel, ssdm);
      PDB(kOutput,1) Info("SetDataMembers()","%s, set %d data members.",
                        (res ? "success" : "failure"), ssdm.GetNumSet());
   } else {
      PDB(kOutput,1) Warning("SetDataMembers","Failed to determine selector TClass!");
   }
   return res;
}

////////////////////////////////////////////////////////////////////////////////
/// Merge another TOutputListSelectorDataMap object, check
/// consistency.

Bool_t TOutputListSelectorDataMap::Merge(TObject* obj)
{
   TOutputListSelectorDataMap* other = dynamic_cast<TOutputListSelectorDataMap*>(obj);
   if (!other) return kFALSE;

   // check for consistency
   TIter iMapping(other->GetMap());
   TNamed* mapping = 0;
   while ((mapping = (TNamed*)iMapping())) {
      TObject* oldMap = fMap->FindObject(mapping->GetName());
      if (!oldMap) {
         fMap->Add(new TNamed(*mapping));
      } else {
         if (strcmp(oldMap->GetTitle(), mapping->GetTitle())) {
            // ouch, contradicting maps!
            PDB(kOutput,1)
               Warning("Merge()",
                       "contradicting mapping for data member `%s' (output list entry `%s' vs. `%s'). "
                       "Cancelling automatic TSelector data member setting!",
                       mapping->GetName(), oldMap->GetTitle(), mapping->GetTitle());
            fMap->Clear();
            return kFALSE;
         }
      }
   }
   return kTRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// Find a TOutputListSelectorDataMap in a collection

TOutputListSelectorDataMap* TOutputListSelectorDataMap::FindInList(TCollection* coll)
{
   TIter iOutput(coll);
   TObject* out = 0;
   TOutputListSelectorDataMap* olsdm = 0;
   while ((out = iOutput())) {
      if (out->InheritsFrom(TOutputListSelectorDataMap::Class())) {
         olsdm = dynamic_cast<TOutputListSelectorDataMap*>(out);
         if (olsdm) break;
      }
   }
   return olsdm;
}
<commit_msg>Revert "Handle TSelectorCint properly by invoking ShowMembers on the interpreted selector"<commit_after>// @(#)root/proofplayer:$Id$
// Author: Axel Naumann, 2010-06-09

/*************************************************************************
 * Copyright (C) 1995-2010, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

/** \class TOutputListSelectorDataMap
\ingroup proofkernel

Set the selector's data members to the corresponding elements of the
output list.

*/

#include "TOutputListSelectorDataMap.h"

#include "TClass.h"
#include "TDataMember.h"
#include "TExMap.h"
#include "THashTable.h"
#include "TList.h"
#include "TMemberInspector.h"
#include "TProofDebug.h"
#include "TSelector.h"

#include <cstddef>

namespace {

   static TClass* IsSettableDataMember(TDataMember* dm) {
      if (!dm || !dm->IsaPointer() || dm->IsBasic()) return 0;
      TString dtTypeName = dm->GetFullTypeName();
      if (!dtTypeName.EndsWith("*")) return 0;
      dtTypeName.Remove(dtTypeName.Length()-1);
      return TClass::GetClass(dtTypeName);
   }

   class TSetSelDataMembers: public TMemberInspector {
   public:
      TSetSelDataMembers(const TOutputListSelectorDataMap& owner, TCollection* dmInfo, TList* output);
      using TMemberInspector::Inspect;
      void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
      Ssiz_t GetNumSet() const { return fNumSet; }
   private:
      TCollection* fDMInfo; // output list object name / member name pairs for output list entries
      TList* fOutputList; // merged output list
      Ssiz_t fNumSet; // number of initialized data members
      const TOutputListSelectorDataMap& fOwner; // owner, used for messaging
   };
}

////////////////////////////////////////////////////////////////////////////////

TSetSelDataMembers::TSetSelDataMembers(const TOutputListSelectorDataMap& owner,
                                       TCollection* dmInfo, TList* output):
   fDMInfo(dmInfo), fOutputList(output), fNumSet(0), fOwner(owner)
{}

////////////////////////////////////////////////////////////////////////////////
/// This method is called by the ShowMembers() method for each
/// data member to recursively collect all base classes' members.
///
///    cl     is the pointer to the current class
///    parent is the parent name (in case of composed objects)
///    name   is the data member name
///    addr   is the data member address

void TSetSelDataMembers::Inspect(TClass *cl, const char* parent, const char *name, const void *addr, Bool_t /* isTransient */)
{
   while (name[0] == '*') ++name;

   TObject* mapping = fDMInfo->FindObject(name);
   if (!mapping) return;

   PDB(kOutput,1) fOwner.Info("SetDataMembers()",
                              "data member `%s%s::%s' maps to output list object `%s'",
                              cl->GetName(), parent, name, mapping->GetTitle());

   TObject* outputObj = fOutputList->FindObject(mapping->GetTitle());
   if (!outputObj) {
      PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
                                    "object `%s' not found in output list!",
                                    mapping->GetTitle());
      return;
   }

   // Check data member type
   TDataMember *dm = cl->GetDataMember(name);
   TClass* cldt = IsSettableDataMember(dm);
   if (!cldt) {
      PDB(kOutput,1) fOwner.Warning("SetDataMembers()",
                                    "unusable data member `%s' should have been detected by TCollectDataMembers!",
                                    name);
      return;
   }

   char *pointer = (char*)addr;
   char **ppointer = (char**)(pointer);
   if (*ppointer) {
      // member points to something - replace instead of delete to not crash on deleting uninitialized values.
      fOwner.Warning("SetDataMembers()", "potential memory leak: replacing data member `%s' != 0. "
                     "Please initialize %s to 0 in constructor %s::%s()",
                     name, name, cl->GetName(), cl->GetName());
   }
   *ppointer = (char*)outputObj;
   ++fNumSet;
}

namespace {
   class TCollectDataMembers: public TMemberInspector {
   public:
      TCollectDataMembers(const TOutputListSelectorDataMap& owner): fOwner(owner) { }
      ~TCollectDataMembers();
      using TMemberInspector::Inspect;
      void Inspect(TClass *cl, const char *parent, const char *name, const void *addr, Bool_t isTransient);
      TExMap& GetMemberPointers() { return fMap; }
   private:
      TExMap fMap; //map of data member's value to TDataMember
      const TOutputListSelectorDataMap& fOwner; //owner, used for messaging
   };
}

////////////////////////////////////////////////////////////////////////////////
/// This method is called by the ShowMembers() method for each
/// data member to recursively collect all base classes' members.
///
///    cl     is the pointer to the current class
///    parent is the parent name (in case of composed objects)
///    name   is the data member name
///    addr   is the data member address

void TCollectDataMembers::Inspect(TClass *cl, const char* /*parent*/, const char *name, const void *addr, Bool_t /* isTransient */)
{
   TDataMember *dm = cl->GetDataMember(name);
   if (!IsSettableDataMember(dm)) return;

   char *pointer = (char*)addr;
   char **ppointer = (char**)(pointer);
   char **p3pointer = (char**)(*ppointer);
   if (p3pointer) {
      // The data member points to something.
      // Handle multiple pointers to the same output list object:
      TObject* prev = (TObject*) (ptrdiff_t)fMap.GetValue((Long64_t)(ptrdiff_t)p3pointer);
      if (prev) {
         // We have a previous entry - is it a data member or already a TList (of data members)?
         if (prev->InheritsFrom(TDataMember::Class())) {
            fMap.Remove((Long64_t)(ptrdiff_t)p3pointer);
            TList* dmList = new TList;
            dmList->Add(prev);
            dmList->Add(dm);
            fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dmList);
         } else {
            TList* prevList = (TList*) prev;
            prevList->Add(dm);
         }
      } else {
         fMap.Add((Long64_t)(ptrdiff_t)p3pointer, (Long64_t)(ptrdiff_t)dm);
      }
      if (name[0] == '*') ++name;
      PDB(kOutput,1) fOwner.Info("Init()", "considering data member `%s'", name);
   }
}

TCollectDataMembers::~TCollectDataMembers() {
   // Destructor

   // Clean up collection of TDataMembers in fMap
   TExMapIter iMembers(&fMap);
   Long64_t key;
   Long64_t value;
   while (iMembers.Next(key, value)) {
      TObject* obj = (TObject*) (ptrdiff_t) value;
      if (obj->InheritsFrom(TList::Class())) {
         delete obj;
      }
   }
}

ClassImp(TOutputListSelectorDataMap);

////////////////////////////////////////////////////////////////////////////////
/// Create a mapper between output list items and TSelector data members.

TOutputListSelectorDataMap::TOutputListSelectorDataMap(TSelector* sel /*= 0*/):
   fMap(0)
{
   if (sel) Init(sel);
}

////////////////////////////////////////////////////////////////////////////////
/// Return static name for TOutputListSelectorDataMap objects.

const char* TOutputListSelectorDataMap::GetName() const
{
   return "PROOF_TOutputListSelectorDataMap_object";
}

////////////////////////////////////////////////////////////////////////////////
/// Initialize the data member <-> output list mapping from a selector.

Bool_t TOutputListSelectorDataMap::Init(TSelector* sel)
{
   if (!sel) {
      PDB(kOutput,1) Warning("Init","Leave (no selector!)");
      return kFALSE;
   }
   TCollection* outList = sel->GetOutputList();
   if (!outList) {
      PDB(kOutput,1) Info("Init()","Leave (no output)");
      return kFALSE;
   }

   if (outList->FindObject(GetName())) {
      // mapping already exists?!
      PDB(kOutput,1) Warning("Init","Mapping already exists!");
      return kFALSE;
   }

   if (fMap) delete fMap;
   fMap = new THashTable;
   fMap->SetOwner();

   TCollectDataMembers cdm(*this);
   if (!sel->IsA()->CallShowMembers(sel, cdm, parent)) {
      // failed to map
      PDB(kOutput,1) Warning("Init","Failed to determine mapping!");
      return kFALSE;
   }
   PDB(kOutput,1) Info("Init()","Found %d data members.",
                        cdm.GetMemberPointers().GetSize());

   // Iterate over output list entries and find data members pointing to the
   // same value. Store that mapping (or a miss).
   TIter iOutput(outList);
   TObject* output;
   TList oneDM;
   while ((output = iOutput())) {
      TObject* obj = (TObject*) (ptrdiff_t)cdm.GetMemberPointers().GetValue((Long64_t)(ptrdiff_t)output);
      if (!obj) continue;

      TList* addAllDM = 0;
      if (obj->InheritsFrom(TDataMember::Class())) {
         oneDM.Add(obj);
         addAllDM = &oneDM;
      } else {
         addAllDM = (TList*) obj;
      }
      TIter iDM(addAllDM);
      TDataMember* dm = 0;
      while ((dm = (TDataMember*) iDM())) {
         fMap->Add(new TNamed(dm->GetName(), output->GetName()));
         PDB(kOutput,1) Info("Init()","Data member `%s' corresponds to output `%s'",
                              dm->GetName(), output->GetName());
      }
      oneDM.Clear();
   }

   return kTRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// Given an output list, set the data members of a TSelector.

Bool_t TOutputListSelectorDataMap::SetDataMembers(TSelector* sel) const
{
   TList* output = sel->GetOutputList();
   if (!output || output->IsEmpty()) return kTRUE;

   Bool_t res = kFALSE;
   // Set fSelector's data members
   TSetSelDataMembers ssdm(*this, fMap, output);
   Bool_t res = sel->IsA()->CallShowMembers(sel, ssdm, parent);
   PDB(kOutput,1) Info("SetDataMembers()","%s, set %d data members.",
                       (res ? "success" : "failure"), ssdm.GetNumSet());
   return res;
}

////////////////////////////////////////////////////////////////////////////////
/// Merge another TOutputListSelectorDataMap object, check
/// consistency.

Bool_t TOutputListSelectorDataMap::Merge(TObject* obj)
{
   TOutputListSelectorDataMap* other = dynamic_cast<TOutputListSelectorDataMap*>(obj);
   if (!other) return kFALSE;

   // check for consistency
   TIter iMapping(other->GetMap());
   TNamed* mapping = 0;
   while ((mapping = (TNamed*)iMapping())) {
      TObject* oldMap = fMap->FindObject(mapping->GetName());
      if (!oldMap) {
         fMap->Add(new TNamed(*mapping));
      } else {
         if (strcmp(oldMap->GetTitle(), mapping->GetTitle())) {
            // ouch, contradicting maps!
            PDB(kOutput,1)
               Warning("Merge()",
                       "contradicting mapping for data member `%s' (output list entry `%s' vs. `%s'). "
                       "Cancelling automatic TSelector data member setting!",
                       mapping->GetName(), oldMap->GetTitle(), mapping->GetTitle());
            fMap->Clear();
            return kFALSE;
         }
      }
   }
   return kTRUE;
}

////////////////////////////////////////////////////////////////////////////////
/// Find a TOutputListSelectorDataMap in a collection

TOutputListSelectorDataMap* TOutputListSelectorDataMap::FindInList(TCollection* coll)
{
   TIter iOutput(coll);
   TObject* out = 0;
   TOutputListSelectorDataMap* olsdm = 0;
   while ((out = iOutput())) {
      if (out->InheritsFrom(TOutputListSelectorDataMap::Class())) {
         olsdm = dynamic_cast<TOutputListSelectorDataMap*>(out);
         if (olsdm) break;
      }
   }
   return olsdm;
}
<|endoftext|>