<commit_before>/* Issues with __local pointers (lp:918801)

   Copyright (c) 2012 Pekka Jääskeläinen / Tampere University of Technology

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

// Enable OpenCL C++ exceptions
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 120
#include <CL/cl2.hpp>

#include <cstdio>
#include <cstdlib>
#include <iostream>

#include "poclu.h"

#define WORK_ITEMS 2
#define BUFFER_SIZE (WORK_ITEMS)

static char
kernelSourceCode[] =
"kernel void test_kernel (global float *a, local int *local_buf, private int scalar)\n"
"{\n"
"   int gid = get_local_id(0); \n"
"   local int automatic_local_scalar; \n"
"   local int automatic_local_buf[2];\n"
"\n"
"   __local int *p;\n"
"\n"
"   p = automatic_local_buf;\n"
"   p[gid] = gid + scalar;\n"
"   p = local_buf;\n"
"   p[gid] = a[gid];\n"
"   automatic_local_scalar = scalar;\n"
"   barrier(CLK_LOCAL_MEM_FENCE);\n"
"   a[gid] = automatic_local_buf[gid] + local_buf[gid] + automatic_local_scalar;\n"
"   \n"
"}\n";

int
main(void)
{
    float A[BUFFER_SIZE];

    try {
        std::vector<cl::Platform> platformList;

        // Pick platform
        cl::Platform::get(&platformList);

        // Pick first platform
        cl_context_properties cprops[] = {
            CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0};
        cl::Context context(CL_DEVICE_TYPE_CPU|CL_DEVICE_TYPE_GPU, cprops);

        // Query the set of devices attched to the context
        std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();

        // Create and program from source
        cl::Program::Sources sources({kernelSourceCode});
        cl::Program program(context, sources);

        cl_device_id dev_id = devices.at(0)();

        int scalar = poclu_bswap_cl_int (dev_id, 4);

        for (int i = 0; i < BUFFER_SIZE; ++i)
            A[i] = poclu_bswap_cl_float(dev_id, (cl_float)i);

        // Build program
        program.build(devices);

        cl::Buffer aBuffer = cl::Buffer(
            context,
            CL_MEM_COPY_HOST_PTR,
            BUFFER_SIZE * sizeof(float),
            (void *) &A[0]);

        cl::Buffer localBuffer = cl::Buffer(
            context, 0, BUFFER_SIZE * sizeof(int), NULL);

        // Create kernel object
        cl::Kernel kernel(program, "test_kernel");

        // Set kernel args
        kernel.setArg(0, aBuffer);
        kernel.setArg(1, localBuffer);
        kernel.setArg(2, scalar);

        // Create command queue
        cl::CommandQueue queue(context, devices[0], 0);

        // Do the work
        queue.enqueueNDRangeKernel(
            kernel,
            cl::NullRange,
            cl::NDRange(WORK_ITEMS),
            cl::NDRange(WORK_ITEMS));

        // Map aBuffer to host pointer. This enforces a sync with
        // the host backing space, remember we choose GPU device.
        float * res = (float *) queue.enqueueMapBuffer(
            aBuffer,
            CL_TRUE, // block
            CL_MAP_READ,
            0,
            BUFFER_SIZE * sizeof(float));

        res[0] = poclu_bswap_cl_float (dev_id, res[0]);
        res[1] = poclu_bswap_cl_float (dev_id, res[1]);
        bool ok = res[0] == 8 && res[1] == 10;
        if (ok) {
            return EXIT_SUCCESS;
        } else {
            std::cout << "NOK " << res[0] << " " << res[1] << std::endl;
            std::cout << "res@" << std::hex << res << std::endl;
            return EXIT_FAILURE;
        }

        // Finally release our hold on accessing the memory
        queue.enqueueUnmapMemObject(
            aBuffer, (void *) res);

        // There is no need to perform a finish on the final unmap
        // or release any objects as this all happens implicitly with
        // the C++ Wrapper API.
    }
    catch (cl::Error err) {
         std::cerr
             << "ERROR: "
             << err.what()
             << "("
             << err.err()
             << ")"
             << std::endl;

         return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<commit_msg>Fix regression/test_locals: do not set localBuffer<commit_after>/* Issues with __local pointers (lp:918801)

   Copyright (c) 2012 Pekka Jääskeläinen / Tampere University of Technology

   Permission is hereby granted, free of charge, to any person obtaining a copy
   of this software and associated documentation files (the "Software"), to deal
   in the Software without restriction, including without limitation the rights
   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   copies of the Software, and to permit persons to whom the Software is
   furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   THE SOFTWARE.
*/

// Enable OpenCL C++ exceptions
#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_MINIMUM_OPENCL_VERSION 120
#define CL_HPP_TARGET_OPENCL_VERSION 120
#include <CL/cl2.hpp>

#include <cstdio>
#include <cstdlib>
#include <iostream>

#include "poclu.h"

#define WORK_ITEMS 2
#define BUFFER_SIZE (WORK_ITEMS)

static char
kernelSourceCode[] =
"kernel void test_kernel (global float *a, local int *local_buf, private int scalar)\n"
"{\n"
"   int gid = get_local_id(0); \n"
"   local int automatic_local_scalar; \n"
"   local int automatic_local_buf[2];\n"
"\n"
"   __local int *p;\n"
"\n"
"   p = automatic_local_buf;\n"
"   p[gid] = gid + scalar;\n"
"   p = local_buf;\n"
"   p[gid] = a[gid];\n"
"   automatic_local_scalar = scalar;\n"
"   barrier(CLK_LOCAL_MEM_FENCE);\n"
"   a[gid] = automatic_local_buf[gid] + local_buf[gid] + automatic_local_scalar;\n"
"   \n"
"}\n";

int
main(void)
{
    float A[BUFFER_SIZE];

    try {
        std::vector<cl::Platform> platformList;

        // Pick platform
        cl::Platform::get(&platformList);

        // Pick first platform
        cl_context_properties cprops[] = {
            CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0};
        cl::Context context(CL_DEVICE_TYPE_CPU|CL_DEVICE_TYPE_GPU, cprops);

        // Query the set of devices attched to the context
        std::vector<cl::Device> devices = context.getInfo<CL_CONTEXT_DEVICES>();

        // Create and program from source
        cl::Program::Sources sources({kernelSourceCode});
        cl::Program program(context, sources);

        cl_device_id dev_id = devices.at(0)();

        int scalar = poclu_bswap_cl_int (dev_id, 4);

        for (int i = 0; i < BUFFER_SIZE; ++i)
            A[i] = poclu_bswap_cl_float(dev_id, (cl_float)i);

        // Build program
        program.build(devices);

        cl::Buffer aBuffer = cl::Buffer(
            context,
            CL_MEM_COPY_HOST_PTR,
            BUFFER_SIZE * sizeof(float),
            (void *) &A[0]);

        // Create kernel object
        cl::Kernel kernel(program, "test_kernel");

        // Set kernel args
        kernel.setArg(0, aBuffer);
        kernel.setArg(1, (BUFFER_SIZE * sizeof(int)), NULL);
        kernel.setArg(2, scalar);

        // Create command queue
        cl::CommandQueue queue(context, devices[0], 0);

        // Do the work
        queue.enqueueNDRangeKernel(
            kernel,
            cl::NullRange,
            cl::NDRange(WORK_ITEMS),
            cl::NDRange(WORK_ITEMS));

        // Map aBuffer to host pointer. This enforces a sync with
        // the host backing space, remember we choose GPU device.
        float * res = (float *) queue.enqueueMapBuffer(
            aBuffer,
            CL_TRUE, // block
            CL_MAP_READ,
            0,
            BUFFER_SIZE * sizeof(float));

        res[0] = poclu_bswap_cl_float (dev_id, res[0]);
        res[1] = poclu_bswap_cl_float (dev_id, res[1]);
        bool ok = res[0] == 8 && res[1] == 10;
        if (ok) {
            return EXIT_SUCCESS;
        } else {
            std::cout << "NOK " << res[0] << " " << res[1] << std::endl;
            std::cout << "res@" << std::hex << res << std::endl;
            return EXIT_FAILURE;
        }

        // Finally release our hold on accessing the memory
        queue.enqueueUnmapMemObject(
            aBuffer, (void *) res);

        // There is no need to perform a finish on the final unmap
        // or release any objects as this all happens implicitly with
        // the C++ Wrapper API.
    }
    catch (cl::Error err) {
         std::cerr
             << "ERROR: "
             << err.what()
             << "("
             << err.err()
             << ")"
             << std::endl;

         return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//

#include "OpusDecoder.h"
#include "audio/Resampler.h"
#include "logging.h"
#include <assert.h>
#include <algorithm>

#include "VoIPController.h"

#define PACKET_SIZE (960*2)

using namespace tgvoip;

tgvoip::OpusDecoder::OpusDecoder(const std::shared_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
	dst->SetCallback(OpusDecoder::Callback, this);
	Initialize(isAsync, needEC);
}

tgvoip::OpusDecoder::OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
	dst->SetCallback(OpusDecoder::Callback, this);
	Initialize(isAsync, needEC);
}

void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC){
	async=isAsync;
	if(async){
		decodedQueue=new BlockingQueue<unsigned char*>(33);
		bufferPool=new BufferPool(PACKET_SIZE, 32);
		semaphore=new Semaphore(32, 0);
	}else{
		decodedQueue=NULL;
		bufferPool=NULL;
		semaphore=NULL;
	}
	dec=opus_decoder_create(48000, 1, NULL);
	if(needEC)
		ecDec=opus_decoder_create(48000, 1, NULL);
	else
		ecDec=NULL;
	buffer=(unsigned char *) malloc(8192);
	lastDecoded=NULL;
	outputBufferSize=0;
	echoCanceller=NULL;
	frameDuration=20;
	consecutiveLostPackets=0;
	enableDTX=false;
	silentPacketCount=0;
	levelMeter=NULL;
	nextLen=0;
	running=false;
	remainingDataLen=0;
	processedBuffer=NULL;
	prevWasEC=false;
	prevLastSample=0;
}

tgvoip::OpusDecoder::~OpusDecoder(){
	opus_decoder_destroy(dec);
	if(ecDec)
		opus_decoder_destroy(ecDec);
	free(buffer);
	if(bufferPool)
		delete bufferPool;
	if(decodedQueue)
		delete decodedQueue;
	if(semaphore)
		delete semaphore;
}

void tgvoip::OpusDecoder::SetEchoCanceller(EchoCanceller* canceller){
	echoCanceller=canceller;
}

size_t tgvoip::OpusDecoder::Callback(unsigned char *data, size_t len, void *param){
	return ((OpusDecoder*)param)->HandleCallback(data, len);
}

size_t tgvoip::OpusDecoder::HandleCallback(unsigned char *data, size_t len){
	if(async){
		if(!running){
			memset(data, 0, len);
			return 0;
		}
		if(outputBufferSize==0){
			outputBufferSize=len;
			int packetsNeeded;
			if(len>PACKET_SIZE)
				packetsNeeded=len/PACKET_SIZE;
			else
				packetsNeeded=1;
			packetsNeeded*=2;
			semaphore->Release(packetsNeeded);
		}
		assert(outputBufferSize==len && "output buffer size is supposed to be the same throughout callbacks");
		if(len==PACKET_SIZE){
			lastDecoded=(unsigned char *) decodedQueue->GetBlocking();
			if(!lastDecoded)
				return 0;
			memcpy(data, lastDecoded, PACKET_SIZE);
			bufferPool->Reuse(lastDecoded);
			semaphore->Release();
			if(silentPacketCount>0){
				silentPacketCount--;
				if(levelMeter)
					levelMeter->Update(reinterpret_cast<int16_t *>(data), 0);
				return 0;
			}
			if(echoCanceller){
				echoCanceller->SpeakerOutCallback(data, PACKET_SIZE);
			}
		}else{
			LOGE("Opus decoder buffer length != 960 samples");
			abort();
		}
	}else{
		if(remainingDataLen==0 && silentPacketCount==0){
			int duration=DecodeNextFrame();
			remainingDataLen=(size_t) (duration/20*960*2);
		}
		if(silentPacketCount>0 || remainingDataLen==0 || !processedBuffer){
			if(silentPacketCount>0)
				silentPacketCount--;
			memset(data, 0, 960*2);
			if(levelMeter)
				levelMeter->Update(reinterpret_cast<int16_t *>(data), 0);
			return 0;
		}
		memcpy(data, processedBuffer, 960*2);
		remainingDataLen-=960*2;
		if(remainingDataLen>0){
			memmove(processedBuffer, processedBuffer+960*2, remainingDataLen);
		}
	}
	if(levelMeter)
		levelMeter->Update(reinterpret_cast<int16_t *>(data), len/2);
	return len;
}

void tgvoip::OpusDecoder::Start(){
	if(!async)
		return;
	running=true;
	thread=new Thread(new MethodPointer<tgvoip::OpusDecoder>(&tgvoip::OpusDecoder::RunThread, this), NULL);
	thread->SetName("opus_decoder");
	thread->SetMaxPriority();
	thread->Start();
}

void tgvoip::OpusDecoder::Stop(){
	if(!running || !async)
		return;
	running=false;
	semaphore->Release();
	thread->Join();
	delete thread;
}

void tgvoip::OpusDecoder::RunThread(void* param){
	int i;
	LOGI("decoder: packets per frame %d", packetsPerFrame);
	while(running){
		int playbackDuration=DecodeNextFrame();
		for(i=0;i<playbackDuration/20;i++){
			semaphore->Acquire();
			if(!running){
				LOGI("==== decoder exiting ====");
				return;
			}
			unsigned char *buf=bufferPool->Get();
			if(buf){
				if(remainingDataLen>0){
					for(std::vector<AudioEffect*>::iterator effect=postProcEffects.begin();effect!=postProcEffects.end();++effect){
						(*effect)->Process(reinterpret_cast<int16_t*>(processedBuffer+(PACKET_SIZE*i)), 960);
					}
					memcpy(buf, processedBuffer+(PACKET_SIZE*i), PACKET_SIZE);
				}else{
					//LOGE("Error decoding, result=%d", size);
					memset(buf, 0, PACKET_SIZE);
				}
				decodedQueue->Put(buf);
			}else{
				LOGW("decoder: no buffers left!");
			}
		}
	}
}

int tgvoip::OpusDecoder::DecodeNextFrame(){
	int playbackDuration=0;
	bool isEC=false;
	size_t len=jitterBuffer->HandleOutput(buffer, 8192, 0, true, playbackDuration, isEC);
	bool fec=false;
	if(!len){
		fec=true;
		len=jitterBuffer->HandleOutput(buffer, 8192, 0, false, playbackDuration, isEC);
		//if(len)
		//	LOGV("Trying FEC...");
	}
	int size;
	if(len){
		size=opus_decode(isEC ? ecDec : dec, buffer, len, (opus_int16 *) decodeBuffer, packetsPerFrame*960, fec ? 1 : 0);
		consecutiveLostPackets=0;
		if(prevWasEC!=isEC && size){
			// It turns out the waveforms generated by the PLC feature are also great to help smooth out the
			// otherwise audible transition between the frames from different decoders. Those are basically an extrapolation
			// of the previous successfully decoded data -- which is exactly what we need here.
			size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16*)nextBuffer, packetsPerFrame*960, 0);
			if(size){
				int16_t* plcSamples=reinterpret_cast<int16_t*>(nextBuffer);
				int16_t* samples=reinterpret_cast<int16_t*>(decodeBuffer);
				constexpr float coeffs[]={0.999802, 0.995062, 0.984031, 0.966778, 0.943413, 0.914084, 0.878975, 0.838309, 0.792344,
										  0.741368, 0.685706, 0.625708, 0.561754, 0.494249, 0.423619, 0.350311, 0.274788, 0.197527, 0.119018, 0.039757};
				for(int i=0;i<20;i++){
					samples[i]=(int16_t)round((plcSamples[i]*coeffs[i]+(float)samples[i]*(1.0-coeffs[i])));
				}
			}
		}
		prevWasEC=isEC;
		prevLastSample=decodeBuffer[size-1];
	}else{ // do packet loss concealment
		consecutiveLostPackets++;
		if(consecutiveLostPackets>2 && enableDTX){
			silentPacketCount+=packetsPerFrame;
			size=packetsPerFrame*960;
		}else{
			size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16 *) decodeBuffer, packetsPerFrame*960, 0);
			//LOGV("PLC");
		}
	}
	if(size<0)
		LOGW("decoder: opus_decode error %d", size);
	remainingDataLen=size;
	if(playbackDuration==80){
		processedBuffer=buffer;
		audio::Resampler::Rescale60To80((int16_t*) decodeBuffer, (int16_t*) processedBuffer);
	}else if(playbackDuration==40){
		processedBuffer=buffer;
		audio::Resampler::Rescale60To40((int16_t*) decodeBuffer, (int16_t*) processedBuffer);
	}else{
		processedBuffer=decodeBuffer;
	}
	return playbackDuration;
}

void tgvoip::OpusDecoder::SetFrameDuration(uint32_t duration){
	frameDuration=duration;
	packetsPerFrame=frameDuration/20;
}

void tgvoip::OpusDecoder::SetJitterBuffer(std::shared_ptr<JitterBuffer> jitterBuffer){
	this->jitterBuffer=jitterBuffer;
}

void tgvoip::OpusDecoder::SetDTX(bool enable){
	enableDTX=enable;
}

void tgvoip::OpusDecoder::SetLevelMeter(AudioLevelMeter *levelMeter){
	this->levelMeter=levelMeter;
}

void tgvoip::OpusDecoder::AddAudioEffect(AudioEffect *effect){
	postProcEffects.push_back(effect);
}

void tgvoip::OpusDecoder::RemoveAudioEffect(AudioEffect *effect){
	std::vector<AudioEffect*>::iterator i=std::find(postProcEffects.begin(), postProcEffects.end(), effect);
	if(i!=postProcEffects.end())
		postProcEffects.erase(i);
}
<commit_msg>Include fix<commit_after>//
// libtgvoip is free and unencumbered public domain software.
// For more information, see http://unlicense.org or the UNLICENSE file
// you should have received with this source code distribution.
//

#include "OpusDecoder.h"
#include "audio/Resampler.h"
#include "logging.h"
#include <assert.h>
#include <math.h>
#include <algorithm>

#include "VoIPController.h"

#define PACKET_SIZE (960*2)

using namespace tgvoip;

tgvoip::OpusDecoder::OpusDecoder(const std::shared_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
	dst->SetCallback(OpusDecoder::Callback, this);
	Initialize(isAsync, needEC);
}

tgvoip::OpusDecoder::OpusDecoder(const std::unique_ptr<MediaStreamItf>& dst, bool isAsync, bool needEC){
	dst->SetCallback(OpusDecoder::Callback, this);
	Initialize(isAsync, needEC);
}

void tgvoip::OpusDecoder::Initialize(bool isAsync, bool needEC){
	async=isAsync;
	if(async){
		decodedQueue=new BlockingQueue<unsigned char*>(33);
		bufferPool=new BufferPool(PACKET_SIZE, 32);
		semaphore=new Semaphore(32, 0);
	}else{
		decodedQueue=NULL;
		bufferPool=NULL;
		semaphore=NULL;
	}
	dec=opus_decoder_create(48000, 1, NULL);
	if(needEC)
		ecDec=opus_decoder_create(48000, 1, NULL);
	else
		ecDec=NULL;
	buffer=(unsigned char *) malloc(8192);
	lastDecoded=NULL;
	outputBufferSize=0;
	echoCanceller=NULL;
	frameDuration=20;
	consecutiveLostPackets=0;
	enableDTX=false;
	silentPacketCount=0;
	levelMeter=NULL;
	nextLen=0;
	running=false;
	remainingDataLen=0;
	processedBuffer=NULL;
	prevWasEC=false;
	prevLastSample=0;
}

tgvoip::OpusDecoder::~OpusDecoder(){
	opus_decoder_destroy(dec);
	if(ecDec)
		opus_decoder_destroy(ecDec);
	free(buffer);
	if(bufferPool)
		delete bufferPool;
	if(decodedQueue)
		delete decodedQueue;
	if(semaphore)
		delete semaphore;
}

void tgvoip::OpusDecoder::SetEchoCanceller(EchoCanceller* canceller){
	echoCanceller=canceller;
}

size_t tgvoip::OpusDecoder::Callback(unsigned char *data, size_t len, void *param){
	return ((OpusDecoder*)param)->HandleCallback(data, len);
}

size_t tgvoip::OpusDecoder::HandleCallback(unsigned char *data, size_t len){
	if(async){
		if(!running){
			memset(data, 0, len);
			return 0;
		}
		if(outputBufferSize==0){
			outputBufferSize=len;
			int packetsNeeded;
			if(len>PACKET_SIZE)
				packetsNeeded=len/PACKET_SIZE;
			else
				packetsNeeded=1;
			packetsNeeded*=2;
			semaphore->Release(packetsNeeded);
		}
		assert(outputBufferSize==len && "output buffer size is supposed to be the same throughout callbacks");
		if(len==PACKET_SIZE){
			lastDecoded=(unsigned char *) decodedQueue->GetBlocking();
			if(!lastDecoded)
				return 0;
			memcpy(data, lastDecoded, PACKET_SIZE);
			bufferPool->Reuse(lastDecoded);
			semaphore->Release();
			if(silentPacketCount>0){
				silentPacketCount--;
				if(levelMeter)
					levelMeter->Update(reinterpret_cast<int16_t *>(data), 0);
				return 0;
			}
			if(echoCanceller){
				echoCanceller->SpeakerOutCallback(data, PACKET_SIZE);
			}
		}else{
			LOGE("Opus decoder buffer length != 960 samples");
			abort();
		}
	}else{
		if(remainingDataLen==0 && silentPacketCount==0){
			int duration=DecodeNextFrame();
			remainingDataLen=(size_t) (duration/20*960*2);
		}
		if(silentPacketCount>0 || remainingDataLen==0 || !processedBuffer){
			if(silentPacketCount>0)
				silentPacketCount--;
			memset(data, 0, 960*2);
			if(levelMeter)
				levelMeter->Update(reinterpret_cast<int16_t *>(data), 0);
			return 0;
		}
		memcpy(data, processedBuffer, 960*2);
		remainingDataLen-=960*2;
		if(remainingDataLen>0){
			memmove(processedBuffer, processedBuffer+960*2, remainingDataLen);
		}
	}
	if(levelMeter)
		levelMeter->Update(reinterpret_cast<int16_t *>(data), len/2);
	return len;
}

void tgvoip::OpusDecoder::Start(){
	if(!async)
		return;
	running=true;
	thread=new Thread(new MethodPointer<tgvoip::OpusDecoder>(&tgvoip::OpusDecoder::RunThread, this), NULL);
	thread->SetName("opus_decoder");
	thread->SetMaxPriority();
	thread->Start();
}

void tgvoip::OpusDecoder::Stop(){
	if(!running || !async)
		return;
	running=false;
	semaphore->Release();
	thread->Join();
	delete thread;
}

void tgvoip::OpusDecoder::RunThread(void* param){
	int i;
	LOGI("decoder: packets per frame %d", packetsPerFrame);
	while(running){
		int playbackDuration=DecodeNextFrame();
		for(i=0;i<playbackDuration/20;i++){
			semaphore->Acquire();
			if(!running){
				LOGI("==== decoder exiting ====");
				return;
			}
			unsigned char *buf=bufferPool->Get();
			if(buf){
				if(remainingDataLen>0){
					for(std::vector<AudioEffect*>::iterator effect=postProcEffects.begin();effect!=postProcEffects.end();++effect){
						(*effect)->Process(reinterpret_cast<int16_t*>(processedBuffer+(PACKET_SIZE*i)), 960);
					}
					memcpy(buf, processedBuffer+(PACKET_SIZE*i), PACKET_SIZE);
				}else{
					//LOGE("Error decoding, result=%d", size);
					memset(buf, 0, PACKET_SIZE);
				}
				decodedQueue->Put(buf);
			}else{
				LOGW("decoder: no buffers left!");
			}
		}
	}
}

int tgvoip::OpusDecoder::DecodeNextFrame(){
	int playbackDuration=0;
	bool isEC=false;
	size_t len=jitterBuffer->HandleOutput(buffer, 8192, 0, true, playbackDuration, isEC);
	bool fec=false;
	if(!len){
		fec=true;
		len=jitterBuffer->HandleOutput(buffer, 8192, 0, false, playbackDuration, isEC);
		//if(len)
		//	LOGV("Trying FEC...");
	}
	int size;
	if(len){
		size=opus_decode(isEC ? ecDec : dec, buffer, len, (opus_int16 *) decodeBuffer, packetsPerFrame*960, fec ? 1 : 0);
		consecutiveLostPackets=0;
		if(prevWasEC!=isEC && size){
			// It turns out the waveforms generated by the PLC feature are also great to help smooth out the
			// otherwise audible transition between the frames from different decoders. Those are basically an extrapolation
			// of the previous successfully decoded data -- which is exactly what we need here.
			size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16*)nextBuffer, packetsPerFrame*960, 0);
			if(size){
				int16_t* plcSamples=reinterpret_cast<int16_t*>(nextBuffer);
				int16_t* samples=reinterpret_cast<int16_t*>(decodeBuffer);
				constexpr float coeffs[]={0.999802, 0.995062, 0.984031, 0.966778, 0.943413, 0.914084, 0.878975, 0.838309, 0.792344,
										  0.741368, 0.685706, 0.625708, 0.561754, 0.494249, 0.423619, 0.350311, 0.274788, 0.197527, 0.119018, 0.039757};
				for(int i=0;i<20;i++){
					samples[i]=(int16_t)round((plcSamples[i]*coeffs[i]+(float)samples[i]*(1.0-coeffs[i])));
				}
			}
		}
		prevWasEC=isEC;
		prevLastSample=decodeBuffer[size-1];
	}else{ // do packet loss concealment
		consecutiveLostPackets++;
		if(consecutiveLostPackets>2 && enableDTX){
			silentPacketCount+=packetsPerFrame;
			size=packetsPerFrame*960;
		}else{
			size=opus_decode(prevWasEC ? ecDec : dec, NULL, 0, (opus_int16 *) decodeBuffer, packetsPerFrame*960, 0);
			//LOGV("PLC");
		}
	}
	if(size<0)
		LOGW("decoder: opus_decode error %d", size);
	remainingDataLen=size;
	if(playbackDuration==80){
		processedBuffer=buffer;
		audio::Resampler::Rescale60To80((int16_t*) decodeBuffer, (int16_t*) processedBuffer);
	}else if(playbackDuration==40){
		processedBuffer=buffer;
		audio::Resampler::Rescale60To40((int16_t*) decodeBuffer, (int16_t*) processedBuffer);
	}else{
		processedBuffer=decodeBuffer;
	}
	return playbackDuration;
}

void tgvoip::OpusDecoder::SetFrameDuration(uint32_t duration){
	frameDuration=duration;
	packetsPerFrame=frameDuration/20;
}

void tgvoip::OpusDecoder::SetJitterBuffer(std::shared_ptr<JitterBuffer> jitterBuffer){
	this->jitterBuffer=jitterBuffer;
}

void tgvoip::OpusDecoder::SetDTX(bool enable){
	enableDTX=enable;
}

void tgvoip::OpusDecoder::SetLevelMeter(AudioLevelMeter *levelMeter){
	this->levelMeter=levelMeter;
}

void tgvoip::OpusDecoder::AddAudioEffect(AudioEffect *effect){
	postProcEffects.push_back(effect);
}

void tgvoip::OpusDecoder::RemoveAudioEffect(AudioEffect *effect){
	std::vector<AudioEffect*>::iterator i=std::find(postProcEffects.begin(), postProcEffects.end(), effect);
	if(i!=postProcEffects.end())
		postProcEffects.erase(i);
}
<|endoftext|>


<commit_before>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "NavierStokesApp.h"
#include "gtest/gtest.h"

// Moose includes
#include "Moose.h"
#include "MooseInit.h"
#include "AppFactory.h"

#include <fstream>
#include <string>

PerfLog Moose::perf_log("gtest");

GTEST_API_ int
main(int argc, char ** argv)
{
  // gtest removes (only) its args from argc and argv - so this  must be before moose init
  testing::InitGoogleTest(&argc, argv);

  MooseInit init(argc, argv);
  registerApp(NavierStokesApp);
  Moose::_throw_on_error = true;

  return RUN_ALL_TESTS();
}
<commit_msg>Update modules/navier_stokes/unit/src/main.C<commit_after>//* This file is part of the MOOSE framework
//* https://www.mooseframework.org
//*
//* All rights reserved, see COPYRIGHT for full restrictions
//* https://github.com/idaholab/moose/blob/master/COPYRIGHT
//*
//* Licensed under LGPL 2.1, please see LICENSE for details
//* https://www.gnu.org/licenses/lgpl-2.1.html

#include "NavierStokesApp.h"
#include "gtest/gtest.h"

// Moose includes
#include "Moose.h"
#include "MooseInit.h"
#include "AppFactory.h"

#include <fstream>
#include <string>

PerfLog Moose::perf_log("gtest");

GTEST_API_ int
main(int argc, char ** argv)
{
  // gtest removes (only) its args from argc and argv - so this must be before moose init
  testing::InitGoogleTest(&argc, argv);

  MooseInit init(argc, argv);
  registerApp(NavierStokesApp);
  Moose::_throw_on_error = true;

  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>/*************************************************************************/
/*  noise_texture.cpp                                                    */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "noise_texture.h"

#include "core/core_string_names.h"

NoiseTexture::NoiseTexture() {
	update_queued = false;
	noise_thread = NULL;
	regen_queued = false;
	first_time = true;

	size = Vector2i(512, 512);
	seamless = false;
	as_normalmap = false;
	bump_strength = 1.0; //1.0 is a little low. Keep at 1.0 for compatibility for now. For 3.2 increase to 8.0.
	flags = FLAGS_DEFAULT;

	noise = Ref<OpenSimplexNoise>();

	texture = VS::get_singleton()->texture_create();

	_queue_update();
}

NoiseTexture::~NoiseTexture() {
	VS::get_singleton()->free(texture);
}

void NoiseTexture::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
	ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);

	ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
	ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);

	ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
	ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);

	ClassDB::bind_method(D_METHOD("set_as_normalmap", "as_normalmap"), &NoiseTexture::set_as_normalmap);
	ClassDB::bind_method(D_METHOD("is_normalmap"), &NoiseTexture::is_normalmap);

	ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture::set_bump_strength);
	ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);

	ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
	ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
	ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
}

void NoiseTexture::_validate_property(PropertyInfo &property) const {

	if (property.name == "bump_strength") {
		if (!as_normalmap) {
			property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
		}
	}
}

void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
	data = p_image;
	if (data.is_valid()) {
		VS::get_singleton()->texture_allocate(texture, size.x, size.y, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, flags);
		VS::get_singleton()->texture_set_data(texture, p_image);
	}
	emit_changed();
}

void NoiseTexture::_thread_done(const Ref<Image> &p_image) {

	_set_texture_data(p_image);
	Thread::wait_to_finish(noise_thread);
	memdelete(noise_thread);
	noise_thread = NULL;
	if (regen_queued) {
		noise_thread = Thread::create(_thread_function, this);
		regen_queued = false;
	}
}

void NoiseTexture::_thread_function(void *p_ud) {
	NoiseTexture *tex = (NoiseTexture *)p_ud;
	tex->call_deferred("_thread_done", tex->_generate_texture());
}

void NoiseTexture::_queue_update() {

	if (update_queued)
		return;

	update_queued = true;
	call_deferred("_update_texture");
}

Ref<Image> NoiseTexture::_generate_texture() {

	update_queued = false;

	if (noise.is_null()) return Ref<Image>();

	Ref<Image> image;

	if (seamless) {
		image = noise->get_seamless_image(size.x);
	} else {
		image = noise->get_image(size.x, size.y);
	}

	if (as_normalmap) {
		image->bumpmap_to_normalmap(bump_strength);
	}

	return image;
}

void NoiseTexture::_update_texture() {
	bool use_thread = true;
	if (first_time) {
		use_thread = false;
		first_time = false;
	}
#ifdef NO_THREADS
	use_thread = false;
#endif
	if (use_thread) {

		if (!noise_thread) {
			noise_thread = Thread::create(_thread_function, this);
			regen_queued = false;
		} else {
			regen_queued = true;
		}

	} else {
		Ref<Image> image = _generate_texture();
		_set_texture_data(image);
	}
}

void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
	if (p_noise == noise)
		return;
	if (noise.is_valid()) {
		noise->disconnect(CoreStringNames::get_singleton()->changed, this, "_update_texture");
	}
	noise = p_noise;
	if (noise.is_valid()) {
		noise->connect(CoreStringNames::get_singleton()->changed, this, "_update_texture");
	}
	_queue_update();
}

Ref<OpenSimplexNoise> NoiseTexture::get_noise() {
	return noise;
}

void NoiseTexture::set_width(int p_width) {
	if (p_width == size.x) return;
	size.x = p_width;
	_queue_update();
}

void NoiseTexture::set_height(int p_height) {
	if (p_height == size.y) return;
	size.y = p_height;
	_queue_update();
}

void NoiseTexture::set_seamless(bool p_seamless) {
	if (p_seamless == seamless) return;
	seamless = p_seamless;
	_queue_update();
}

bool NoiseTexture::get_seamless() {
	return seamless;
}

void NoiseTexture::set_as_normalmap(bool p_as_normalmap) {
	if (p_as_normalmap == as_normalmap) return;
	as_normalmap = p_as_normalmap;
	_queue_update();
	_change_notify();
}

bool NoiseTexture::is_normalmap() {
	return as_normalmap;
}

void NoiseTexture::set_bump_strength(float p_bump_strength) {

	if (p_bump_strength == bump_strength) return;
	bump_strength = p_bump_strength;
	if (as_normalmap)
		_queue_update();
}

float NoiseTexture::get_bump_strength() {

	return bump_strength;
}

int NoiseTexture::get_width() const {

	return size.x;
}

int NoiseTexture::get_height() const {

	return size.y;
}

void NoiseTexture::set_flags(uint32_t p_flags) {
	flags = p_flags;
	VS::get_singleton()->texture_set_flags(texture, flags);
}

uint32_t NoiseTexture::get_flags() const {
	return flags;
}

Ref<Image> NoiseTexture::get_data() const {

	return data;
}
<commit_msg>changed default noisetexture strength<commit_after>/*************************************************************************/
/*  noise_texture.cpp                                                    */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md)    */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "noise_texture.h"

#include "core/core_string_names.h"

NoiseTexture::NoiseTexture() {
	update_queued = false;
	noise_thread = NULL;
	regen_queued = false;
	first_time = true;

	size = Vector2i(512, 512);
	seamless = false;
	as_normalmap = false;
	bump_strength = 8.0;
	flags = FLAGS_DEFAULT;

	noise = Ref<OpenSimplexNoise>();

	texture = VS::get_singleton()->texture_create();

	_queue_update();
}

NoiseTexture::~NoiseTexture() {
	VS::get_singleton()->free(texture);
}

void NoiseTexture::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_width", "width"), &NoiseTexture::set_width);
	ClassDB::bind_method(D_METHOD("set_height", "height"), &NoiseTexture::set_height);

	ClassDB::bind_method(D_METHOD("set_noise", "noise"), &NoiseTexture::set_noise);
	ClassDB::bind_method(D_METHOD("get_noise"), &NoiseTexture::get_noise);

	ClassDB::bind_method(D_METHOD("set_seamless", "seamless"), &NoiseTexture::set_seamless);
	ClassDB::bind_method(D_METHOD("get_seamless"), &NoiseTexture::get_seamless);

	ClassDB::bind_method(D_METHOD("set_as_normalmap", "as_normalmap"), &NoiseTexture::set_as_normalmap);
	ClassDB::bind_method(D_METHOD("is_normalmap"), &NoiseTexture::is_normalmap);

	ClassDB::bind_method(D_METHOD("set_bump_strength", "bump_strength"), &NoiseTexture::set_bump_strength);
	ClassDB::bind_method(D_METHOD("get_bump_strength"), &NoiseTexture::get_bump_strength);

	ClassDB::bind_method(D_METHOD("_update_texture"), &NoiseTexture::_update_texture);
	ClassDB::bind_method(D_METHOD("_generate_texture"), &NoiseTexture::_generate_texture);
	ClassDB::bind_method(D_METHOD("_thread_done", "image"), &NoiseTexture::_thread_done);

	ADD_PROPERTY(PropertyInfo(Variant::INT, "width", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_width", "get_width");
	ADD_PROPERTY(PropertyInfo(Variant::INT, "height", PROPERTY_HINT_RANGE, "1,2048,1,or_greater"), "set_height", "get_height");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "seamless"), "set_seamless", "get_seamless");
	ADD_PROPERTY(PropertyInfo(Variant::BOOL, "as_normalmap"), "set_as_normalmap", "is_normalmap");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "bump_strength", PROPERTY_HINT_RANGE, "0,32,0.1,or_greater"), "set_bump_strength", "get_bump_strength");
	ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "noise", PROPERTY_HINT_RESOURCE_TYPE, "OpenSimplexNoise"), "set_noise", "get_noise");
}

void NoiseTexture::_validate_property(PropertyInfo &property) const {

	if (property.name == "bump_strength") {
		if (!as_normalmap) {
			property.usage = PROPERTY_USAGE_NOEDITOR | PROPERTY_USAGE_INTERNAL;
		}
	}
}

void NoiseTexture::_set_texture_data(const Ref<Image> &p_image) {
	data = p_image;
	if (data.is_valid()) {
		VS::get_singleton()->texture_allocate(texture, size.x, size.y, 0, Image::FORMAT_RGBA8, VS::TEXTURE_TYPE_2D, flags);
		VS::get_singleton()->texture_set_data(texture, p_image);
	}
	emit_changed();
}

void NoiseTexture::_thread_done(const Ref<Image> &p_image) {

	_set_texture_data(p_image);
	Thread::wait_to_finish(noise_thread);
	memdelete(noise_thread);
	noise_thread = NULL;
	if (regen_queued) {
		noise_thread = Thread::create(_thread_function, this);
		regen_queued = false;
	}
}

void NoiseTexture::_thread_function(void *p_ud) {
	NoiseTexture *tex = (NoiseTexture *)p_ud;
	tex->call_deferred("_thread_done", tex->_generate_texture());
}

void NoiseTexture::_queue_update() {

	if (update_queued)
		return;

	update_queued = true;
	call_deferred("_update_texture");
}

Ref<Image> NoiseTexture::_generate_texture() {

	update_queued = false;

	if (noise.is_null()) return Ref<Image>();

	Ref<Image> image;

	if (seamless) {
		image = noise->get_seamless_image(size.x);
	} else {
		image = noise->get_image(size.x, size.y);
	}

	if (as_normalmap) {
		image->bumpmap_to_normalmap(bump_strength);
	}

	return image;
}

void NoiseTexture::_update_texture() {
	bool use_thread = true;
	if (first_time) {
		use_thread = false;
		first_time = false;
	}
#ifdef NO_THREADS
	use_thread = false;
#endif
	if (use_thread) {

		if (!noise_thread) {
			noise_thread = Thread::create(_thread_function, this);
			regen_queued = false;
		} else {
			regen_queued = true;
		}

	} else {
		Ref<Image> image = _generate_texture();
		_set_texture_data(image);
	}
}

void NoiseTexture::set_noise(Ref<OpenSimplexNoise> p_noise) {
	if (p_noise == noise)
		return;
	if (noise.is_valid()) {
		noise->disconnect(CoreStringNames::get_singleton()->changed, this, "_update_texture");
	}
	noise = p_noise;
	if (noise.is_valid()) {
		noise->connect(CoreStringNames::get_singleton()->changed, this, "_update_texture");
	}
	_queue_update();
}

Ref<OpenSimplexNoise> NoiseTexture::get_noise() {
	return noise;
}

void NoiseTexture::set_width(int p_width) {
	if (p_width == size.x) return;
	size.x = p_width;
	_queue_update();
}

void NoiseTexture::set_height(int p_height) {
	if (p_height == size.y) return;
	size.y = p_height;
	_queue_update();
}

void NoiseTexture::set_seamless(bool p_seamless) {
	if (p_seamless == seamless) return;
	seamless = p_seamless;
	_queue_update();
}

bool NoiseTexture::get_seamless() {
	return seamless;
}

void NoiseTexture::set_as_normalmap(bool p_as_normalmap) {
	if (p_as_normalmap == as_normalmap) return;
	as_normalmap = p_as_normalmap;
	_queue_update();
	_change_notify();
}

bool NoiseTexture::is_normalmap() {
	return as_normalmap;
}

void NoiseTexture::set_bump_strength(float p_bump_strength) {

	if (p_bump_strength == bump_strength) return;
	bump_strength = p_bump_strength;
	if (as_normalmap)
		_queue_update();
}

float NoiseTexture::get_bump_strength() {

	return bump_strength;
}

int NoiseTexture::get_width() const {

	return size.x;
}

int NoiseTexture::get_height() const {

	return size.y;
}

void NoiseTexture::set_flags(uint32_t p_flags) {
	flags = p_flags;
	VS::get_singleton()->texture_set_flags(texture, flags);
}

uint32_t NoiseTexture::get_flags() const {
	return flags;
}

Ref<Image> NoiseTexture::get_data() const {

	return data;
}
<|endoftext|>


<commit_before>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef NdbApi_H
#define NdbApi_H

#include "ndbapi_limits.h"
#include "Ndb.hpp"
#include "NdbConnection.hpp"
#include "NdbOperation.hpp"
#include "NdbScanOperation.hpp"
#include "NdbIndexOperation.hpp"
#include "NdbIndexScanOperation.hpp"
#include "NdbScanFilter.hpp"
#include "NdbRecAttr.hpp"
#include "NdbResultSet.hpp"
#include "NdbDictionary.hpp"
#include "NdbEventOperation.hpp"
#include "NdbPool.hpp"
#include "NdbBlob.hpp"
#endif
<commit_msg>NdbApi.hpp:   NdbApi.hpp to include ndb_inti.h and ndb_cluster_connecion.hpp<commit_after>/* Copyright (C) 2003 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program 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 General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#ifndef NdbApi_H
#define NdbApi_H

#include "ndb_init.h"
#include "ndb_cluster_connection.hpp"
#include "ndbapi_limits.h"
#include "Ndb.hpp"
#include "NdbConnection.hpp"
#include "NdbOperation.hpp"
#include "NdbScanOperation.hpp"
#include "NdbIndexOperation.hpp"
#include "NdbIndexScanOperation.hpp"
#include "NdbScanFilter.hpp"
#include "NdbRecAttr.hpp"
#include "NdbResultSet.hpp"
#include "NdbDictionary.hpp"
#include "NdbEventOperation.hpp"
#include "NdbPool.hpp"
#include "NdbBlob.hpp"
#endif
<|endoftext|>


<commit_before>// (c) 2012 Cloudera, Inc. All rights reserved.
#include <stdio.h>
#include <string>
#include <map>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <gflags/gflags.h>
#include <glog/logging.h>

#include "util/webserver.h"

using namespace std;
using namespace boost;
using namespace google;

DEFINE_int32(webserver_port, 8080, "Port to start debug webserver on");
DEFINE_string(webserver_interface, "",
    "Interface to start debug webserver on. If blank, webserver binds to 0.0.0.0");
DEFINE_bool(no_webserver, false, "If true, debug webserver is not started");

namespace impala {

Webserver::Webserver()
  : port_(FLAGS_webserver_port),
    interface_(FLAGS_webserver_interface),
    context_(NULL) {

}

Webserver::Webserver(const string& interface, const int port)
  : port_(port),
    interface_(interface) {

}

Webserver::~Webserver() {
  Stop();
}

void Webserver::FlagsHandler(stringstream* output) {
  (*output) << "
" << CommandlineFlagsIntoString() << "
";
}

void Webserver::RootHandler(stringstream* output) {
  // path_handler_lock_ already held by MongooseCallback
  BOOST_FOREACH(const PathHandlerMap::value_type& handler, path_handlers_) {
    (*output) << "<a href=\"" << handler.first << "\">" << handler.first << "
";
  }
}

Status Webserver::Start() {
  if (FLAGS_no_webserver) {
    VLOG(1) << "Not starting webserver";
    return Status::OK;
  }

  VLOG(1) << "Starting webserver on " << interface_
          << (interface_.empty() ? "all interfaces, port " : ":") << port_;

  string port_as_string = boost::lexical_cast<string>(port_);
  stringstream listening_spec;
  listening_spec << interface_ << (interface_.empty() ? "" : ":") << port_as_string;
  const char* options[] = {"listening_ports", listening_spec.str().c_str(), NULL};

  // To work around not being able to pass member functions as C callbacks, we store a
  // pointer to this server in the per-server state, and register a static method as the
  // default callback. That method unpacks the pointer to this and calls the real
  // callback.
  context_ = mg_start(&Webserver::MongooseCallbackStatic, reinterpret_cast<void*>(this),
      options);

  if (context_ == NULL) {
    stringstream error_msg;
    error_msg << "Could not start webserver on port: " << port_;
    return Status(error_msg.str());
  }

  PathHandlerCallback default_callback =
      bind<void>(mem_fn(&Webserver::RootHandler), this, _1);

  RegisterPathHandler("/", default_callback);

  PathHandlerCallback flags_callback =
      bind<void>(mem_fn(&Webserver::FlagsHandler), this, _1);

  RegisterPathHandler("/flags", flags_callback);

  VLOG(1) << "Webserver started";
  return Status::OK;
}

void Webserver::Stop() {
  if (context_ != NULL) mg_stop(context_);
}

void* Webserver::MongooseCallbackStatic(enum mg_event event,
    struct mg_connection* connection, const struct mg_request_info* request_info) {
  Webserver* instance = reinterpret_cast<Webserver*>(request_info->user_data);
  return instance->MongooseCallback(event, connection, request_info);
}

// Mongoose requires a non-null return from the callback to signify successful processing
static void* PROCESSING_COMPLETE = reinterpret_cast<void*>(1);

void* Webserver::MongooseCallback(enum mg_event event, struct mg_connection* connection,
    const struct mg_request_info* request_info) {
  if (event == MG_NEW_REQUEST) {
    mutex::scoped_lock lock(path_handlers_lock_);
    PathHandlerMap::const_iterator it = path_handlers_.find(request_info->uri);
    if (it == path_handlers_.end()) {
      mg_printf(connection, "HTTP/1.1 404 Not Found\r\n"
                            "Content-Type: text/plain\r\n\r\n");
      mg_printf(connection, "No handler for URI %s\r\n\r\n", request_info->uri);
      return PROCESSING_COMPLETE;
    }

    mg_printf(connection, "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/html\r\n\r\n");
    // TODO: Consider adding simple HTML boilerplate, e.g.  ...
    stringstream output;
    BOOST_FOREACH(const PathHandlerCallback& callback, it->second) {
      callback(&output);
    }

    mg_printf(connection, "%s", output.str().c_str());
    return PROCESSING_COMPLETE;
  } else {
    return NULL;
  }
}

void Webserver::RegisterPathHandler(const std::string& path,
   const PathHandlerCallback& callback) {
  mutex::scoped_lock lock(path_handlers_lock_);
  // operator [] constructs an entry if one does not exist
  path_handlers_[path].push_back(callback);
}

}
<commit_msg>Fix linking errors in webserver<commit_after>// (c) 2012 Cloudera, Inc. All rights reserved.
#include <stdio.h>
#include <string>
#include <map>
#include <boost/lexical_cast.hpp>
#include <boost/foreach.hpp>
#include <boost/bind.hpp>
#include <boost/mem_fn.hpp>
#include <glog/logging.h>
#include <gflags/gflags.h>

#include "util/webserver.h"

using namespace std;
using namespace boost;
using namespace google;

DEFINE_int32(webserver_port, 8080, "Port to start debug webserver on");
DEFINE_string(webserver_interface, "",
    "Interface to start debug webserver on. If blank, webserver binds to 0.0.0.0");
DEFINE_bool(no_webserver, false, "If true, debug webserver is not started");

namespace impala {

Webserver::Webserver()
  : port_(FLAGS_webserver_port),
    interface_(FLAGS_webserver_interface),
    context_(NULL) {

}

Webserver::Webserver(const string& interface, const int port)
  : port_(port),
    interface_(interface) {

}

Webserver::~Webserver() {
  Stop();
}

void Webserver::FlagsHandler(stringstream* output) {
  (*output) << "
" << CommandlineFlagsIntoString() << "
";
}

void Webserver::RootHandler(stringstream* output) {
  // path_handler_lock_ already held by MongooseCallback
  BOOST_FOREACH(const PathHandlerMap::value_type& handler, path_handlers_) {
    (*output) << "<a href=\"" << handler.first << "\">" << handler.first << "
";
  }
}

Status Webserver::Start() {
  if (FLAGS_no_webserver) {
    VLOG(1) << "Not starting webserver";
    return Status::OK;
  }

  VLOG(1) << "Starting webserver on " << interface_
          << (interface_.empty() ? "all interfaces, port " : ":") << port_;

  string port_as_string = boost::lexical_cast<string>(port_);
  stringstream listening_spec;
  listening_spec << interface_ << (interface_.empty() ? "" : ":") << port_as_string;
  const char* options[] = {"listening_ports", listening_spec.str().c_str(), NULL};

  // To work around not being able to pass member functions as C callbacks, we store a
  // pointer to this server in the per-server state, and register a static method as the
  // default callback. That method unpacks the pointer to this and calls the real
  // callback.
  context_ = mg_start(&Webserver::MongooseCallbackStatic, reinterpret_cast<void*>(this),
      options);

  if (context_ == NULL) {
    stringstream error_msg;
    error_msg << "Could not start webserver on port: " << port_;
    return Status(error_msg.str());
  }

  PathHandlerCallback default_callback =
      bind<void>(mem_fn(&Webserver::RootHandler), this, _1);

  RegisterPathHandler("/", default_callback);

  PathHandlerCallback flags_callback =
      bind<void>(mem_fn(&Webserver::FlagsHandler), this, _1);

  RegisterPathHandler("/flags", flags_callback);

  VLOG(1) << "Webserver started";
  return Status::OK;
}

void Webserver::Stop() {
  if (context_ != NULL) mg_stop(context_);
}

void* Webserver::MongooseCallbackStatic(enum mg_event event,
    struct mg_connection* connection, const struct mg_request_info* request_info) {
  Webserver* instance = reinterpret_cast<Webserver*>(request_info->user_data);
  return instance->MongooseCallback(event, connection, request_info);
}

// Mongoose requires a non-null return from the callback to signify successful processing
static void* PROCESSING_COMPLETE = reinterpret_cast<void*>(1);

void* Webserver::MongooseCallback(enum mg_event event, struct mg_connection* connection,
    const struct mg_request_info* request_info) {
  if (event == MG_NEW_REQUEST) {
    mutex::scoped_lock lock(path_handlers_lock_);
    PathHandlerMap::const_iterator it = path_handlers_.find(request_info->uri);
    if (it == path_handlers_.end()) {
      mg_printf(connection, "HTTP/1.1 404 Not Found\r\n"
                            "Content-Type: text/plain\r\n\r\n");
      mg_printf(connection, "No handler for URI %s\r\n\r\n", request_info->uri);
      return PROCESSING_COMPLETE;
    }

    mg_printf(connection, "HTTP/1.1 200 OK\r\n"
              "Content-Type: text/html\r\n\r\n");
    // TODO: Consider adding simple HTML boilerplate, e.g.  ...
    stringstream output;
    BOOST_FOREACH(const PathHandlerCallback& callback, it->second) {
      callback(&output);
    }

    mg_printf(connection, "%s", output.str().c_str());
    return PROCESSING_COMPLETE;
  } else {
    return NULL;
  }
}

void Webserver::RegisterPathHandler(const std::string& path,
   const PathHandlerCallback& callback) {
  mutex::scoped_lock lock(path_handlers_lock_);
  // operator [] constructs an entry if one does not exist
  path_handlers_[path].push_back(callback);
}

}
<|endoftext|>


<commit_before>#include <benchmark/benchmark.h>

#include <blackhole/attribute.hpp>
#include <blackhole/attributes.hpp>
#include <blackhole/cpp17/string_view.hpp>
#include <blackhole/extensions/writer.hpp>
#include <blackhole/formatter/json.hpp>
#include <blackhole/record.hpp>

#include "mod.hpp"

namespace blackhole {
namespace benchmark {

using ::blackhole::formatter::json_t;

static void format_json(::benchmark::State& state) {
    json_t formatter;

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"message"})
        .build();

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed_attr(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"endpoint"})
        .build();

    const string_view message("value");
    const attribute_list attributes{{"endpoint", "127.0.0.1:8080"}};
    const attribute_pack pack{attributes};
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

NBENCHMARK("formatter.json", format_json);
NBENCHMARK("formatter.json[route]", format_json_message_routed);
NBENCHMARK("formatter.json[route + attr: 1]", format_json_message_routed_attr);

}  // namespace benchmark
}  // namespace blackhole
<commit_msg>feat(bench): add real-world example<commit_after>#include <benchmark/benchmark.h>

#include <blackhole/attribute.hpp>
#include <blackhole/attributes.hpp>
#include <blackhole/cpp17/string_view.hpp>
#include <blackhole/extensions/writer.hpp>
#include <blackhole/formatter/json.hpp>
#include <blackhole/record.hpp>

#include "mod.hpp"

namespace blackhole {
namespace benchmark {

using ::blackhole::formatter::json_t;

static void format_json(::benchmark::State& state) {
    json_t formatter;

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"message"})
        .build();

    const string_view message("value");
    const attribute_pack pack;
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed_attr(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"endpoint"})
        .build();

    const string_view message("value");
    const attribute_list attributes{{"endpoint", "127.0.0.1:8080"}};
    const attribute_pack pack{attributes};
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed_attr5(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"endpoint", "severity", "process", "thread"})
        .build();

    const string_view message("registering component 'storage' in category 'cocaine::api::service_t'");
    const attribute_list attributes{
        {"endpoint",  "127.0.0.1:8080"},
        {"source",    "app/testing"   },
        {"requestid", 100500          },
        {"spanid",    0               },
        {"spanid",    42              }
    };
    const attribute_pack pack{attributes};
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

static void format_json_message_routed_attr5_unique(::benchmark::State& state) {
    auto formatter = json_t::builder_t()
        .route("/fields", {"endpoint", "severity", "process", "thread"})
        .unique()
        .build();

    const string_view message("registering component 'storage' in category 'cocaine::api::service_t'");
    const attribute_list attributes{
        {"endpoint",  "127.0.0.1:8080"},
        {"source",    "app/testing"   },
        {"requestid", 100500          },
        {"spanid",    0               },
        {"spanid",    42              }
    };
    const attribute_pack pack{attributes};
    record_t record(0, message, pack);
    writer_t writer;

    while (state.KeepRunning()) {
        formatter.format(record, writer);
        writer.inner.clear();
    }

    state.SetItemsProcessed(state.iterations());
}

NBENCHMARK("formatter.json", format_json);
NBENCHMARK("formatter.json[route]", format_json_message_routed);
NBENCHMARK("formatter.json[route + attr: 1]", format_json_message_routed_attr);
NBENCHMARK("formatter.json[route + attr: 5]", format_json_message_routed_attr5);
NBENCHMARK("formatter.json[route + attr: 5 + unique]", format_json_message_routed_attr5_unique);

}  // namespace benchmark
}  // namespace blackhole
<|endoftext|>


<commit_before>#include "Output.h"

#include "Parser.h"
#include "PerformanceTracker.h"

#include "pica/utility/Utility.h"
#include "pica/threading/OpenMPHelper.h"

#include <iostream>
#include <map>
#include <string>

using namespace pica;
using namespace std;

map<PerformanceTracker::Stage, string> getStageNames();

void printHeader()
{
    string message = "pica benchmark, ";
    if (useOpenMP())
        message += toString(getNumThreads()) + " OpenMP threads.";
    else
        message += "OpenMP disabled.";
    cout << message << "\n";
}

void printParameters(const Parameters& parameters)
{
    cout << "\nParameters:\n";
    cout << "Dimension = " << parameters.dimension << "\n";
    cout << "Grid size = " << toString(parameters.numCells) << "\n";
    cout << parameters.numIterations << " time steps\n";
}

void printPerformance(const PerformanceTracker& tracker)
{
    cout << "\nPerformance results:\n";
    map<PerformanceTracker::Stage, string> stageNames = getStageNames();
    PerformanceTracker::StageTime stageTime = tracker.getStageTime();
    for (PerformanceTracker::StageTime::iterator i = stageTime.begin(); i != stageTime.end(); i++)
        cout << stageNames[i->first] << ": " << i->second << " sec.\n";
}

map<PerformanceTracker::Stage, string> getStageNames()
{
    map<PerformanceTracker::Stage, string> names;
    names[PerformanceTracker::Stage_CurrentDeposition] = "Current deposition";
    names[PerformanceTracker::Stage_FieldSolver] = "Field solver";
    names[PerformanceTracker::Stage_ParticleLoop] = "Particle loop";
    return names;
}
<commit_msg>Add prefixes for output of parameters and performance data.<commit_after>#include "Output.h"

#include "Parser.h"
#include "PerformanceTracker.h"

#include "pica/utility/Utility.h"
#include "pica/threading/OpenMPHelper.h"

#include <iostream>
#include <map>
#include <string>

using namespace pica;
using namespace std;

map<PerformanceTracker::Stage, string> getStageNames();

string getPrefix()
{
    return "   ";
}

void printHeader()
{
    string message = "pica benchmark, ";
    if (useOpenMP())
        message += toString(getNumThreads()) + " OpenMP threads.";
    else
        message += "OpenMP disabled.";
    cout << message << "\n";
}

void printParameters(const Parameters& parameters)
{
    string prefix = getPrefix();
    cout << "\nParameters:\n";
    cout << prefix << "Dimension = " << parameters.dimension << "\n";
    cout << prefix << "Grid size = " << toString(parameters.numCells) << "\n";
    cout << prefix << parameters.numIterations << " time steps\n";
}

void printPerformance(const PerformanceTracker& tracker)
{
    string prefix = getPrefix();
    cout << "\nPerformance results:\n";
    map<PerformanceTracker::Stage, string> stageNames = getStageNames();
    PerformanceTracker::StageTime stageTime = tracker.getStageTime();
    for (PerformanceTracker::StageTime::iterator i = stageTime.begin(); i != stageTime.end(); i++)
        cout << prefix << stageNames[i->first] << ": " << i->second << " sec.\n";
}

map<PerformanceTracker::Stage, string> getStageNames()
{
    map<PerformanceTracker::Stage, string> names;
    names[PerformanceTracker::Stage_CurrentDeposition] = "Current deposition";
    names[PerformanceTracker::Stage_FieldSolver] = "Field solver";
    names[PerformanceTracker::Stage_ParticleLoop] = "Particle loop";
    return names;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: singlebackendadapter.cxx,v $
 *
 *  $Revision: 1.10 $
 *
 *  last change: $Author: hr $ $Date: 2004-06-18 15:49:07 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_
#include "singlebackendadapter.hxx"
#endif // CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_

#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif // CONFIGMGR_API_FACTORY_HXX_

#ifndef CONFIGMGR_SERVICEINFOHELPER_HXX_
#include "serviceinfohelper.hxx"
#endif // CONFIGMGR_SERVICEINFOHELPER_HXX_

#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XMULTILAYERSTRATUM_HPP_
#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
#endif
#ifndef _COM_SUN_STAR_CONFIGURATION_CANNOTLOADCONFIGURATIONEXCEPTION_HPP_
#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
namespace configmgr { namespace backend {

//==============================================================================

SingleBackendAdapter::SingleBackendAdapter(
        const uno::Reference<uno::XComponentContext>& xContext)
        : BackendBase(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) {
}
//------------------------------------------------------------------------------

SingleBackendAdapter::~SingleBackendAdapter(void) {}
//------------------------------------------------------------------------------

void SAL_CALL SingleBackendAdapter::initialize(
        const uno::Sequence<uno::Any>& aParameters)
    throw (uno::RuntimeException, uno::Exception) {

    uno::Any const * const pParams = aParameters.getConstArray();
    sal_Int32 nCount = aParameters.getLength();

    for (sal_Int32 ix = 0; ix < nCount; ++ix)
    {
        if (pParams[ix] >>= mBackend) break;
    }

    if (!mBackend.is())
    {
        throw com::sun::star::configuration::CannotLoadConfigurationException(
            OUString::createFromAscii("Online SingleBackend Adapter: Cannot operate without real (Single)Backend"),
            *this);
    }
}
//------------------------------------------------------------------------------
static inline OUString getSingleLayerDummyEntity()
{ return OUString(RTL_CONSTASCII_USTRINGPARAM("*")); }
//------------------------------------------------------------------------------
bool SingleBackendAdapter::checkOkState()
{
    if (!mBackend.is())
    {
        if(rBHelper.bDisposed)
        {
            throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Backend already disposed")),*this);
        }
        else
        {
            throw backenduno::BackendAccessException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this,uno::Any() );
        }
    }
    return true;
}

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

// XBackendEntities
rtl::OUString SAL_CALL
    SingleBackendAdapter::getOwnerEntity(  )
        throw (uno::RuntimeException)
{
    if (mBackend.is())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );

        return xEntities->getOwnerEntity();
    }
    else
    {
        throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this);
    }
}
//------------------------------------------------------------------------------

rtl::OUString SAL_CALL
    SingleBackendAdapter::getAdminEntity(  )
        throw (uno::RuntimeException)
{
    if (mBackend.is())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->getAdminEntity();
    }
    else
    {
        throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this);
    }
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::supportsEntity( const rtl::OUString& aEntity )
    throw (backenduno::BackendAccessException, uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->supportsEntity(aEntity);
    }
    return false;
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->isEqualEntity(aEntity,aOtherEntity);
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XSchema> SAL_CALL
    SingleBackendAdapter::getComponentSchema(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return mBackend->getComponentSchema(aComponent) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
    SingleBackendAdapter::listOwnLayers(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return listLayers(aComponent, this->getOwnerEntity()) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XUpdateHandler> SAL_CALL
    SingleBackendAdapter::getOwnUpdateHandler(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::NoSupportException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return getUpdateHandler(aComponent, this->getOwnerEntity()) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
    SingleBackendAdapter::listLayers(const rtl::OUString& aComponent,
                                          const rtl::OUString& aEntity)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );

        uno::Sequence<uno::Reference<backenduno::XLayer> > retCode =
            xBackend->getLayers(xBackend->listLayerIds(aComponent, aEntity),
                            rtl::OUString()) ;

        // There might be non-existent layers in the list if there's no
        // actual data associated to a given layer id. Hence we have to
        // compress the list.
        sal_Int32 maxLayer = 0 ;

        for (sal_Int32 i = 0 ; i < retCode.getLength() ; ++ i)
        {
            if (retCode [i].is())
            {
                if (i != maxLayer) { retCode [maxLayer] = retCode [i] ; }
                ++ maxLayer ;
            }
        }
        retCode.realloc(maxLayer) ;
        return retCode ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XUpdateHandler> SAL_CALL
    SingleBackendAdapter::getUpdateHandler(const rtl::OUString& aComponent,
                                                const rtl::OUString& aEntity)
        throw (backenduno::BackendAccessException,
                lang::NoSupportException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );

        uno::Sequence<uno::Any> arguments(1) ;

        arguments [0] <<= xBackend->getUpdatableLayer(
                                        xBackend->getUpdateLayerId(aComponent,
                                                                   aEntity)) ;
        uno::Reference< uno::XInterface > xHandler;
        try
        {
            const rtl::OUString kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.LayerUpdateMerger")) ;

            xHandler = mFactory->createInstanceWithArguments(kUpdateMerger, arguments);
        }
        catch (uno::RuntimeException & )
        {throw;}
        catch (uno::Exception & e)
        {
            const rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM(
                "Configuration SingleBackendAdapter: Cannot create UpdateMerger - error message: ")) ;
            throw uno::RuntimeException(sMessage.concat(e.Message),*this);
        }

        return uno::Reference<backenduno::XUpdateHandler>(xHandler, uno::UNO_REF_QUERY_THROW) ;
    }
    return false;
}
//------------------------------------------------------------------------------

static const sal_Char * const kBackendService = "com.sun.star.configuration.backend.Backend" ;
static const sal_Char * const kAdapterService = "com.sun.star.configuration.backend.BackendAdapter" ;
static const sal_Char * const kOnlineService  = "com.sun.star.configuration.backend.OnlineBackend" ;

static const sal_Char * const kImplementation =
                "com.sun.star.comp.configuration.backend.SingleBackendAdapter" ;

static const AsciiServiceName kServiceNames [] =
{
    kOnlineService,
    kAdapterService,
    0,
    kBackendService,
    0
} ;
static const ServiceImplementationInfo kServiceInfo =
{
    kImplementation,
    kServiceNames,
    kServiceNames + 3
} ;

const ServiceRegistrationInfo *getSingleBackendAdapterServiceInfo()
{
    return getRegistrationInfo(&kServiceInfo) ;
}

uno::Reference<uno::XInterface> SAL_CALL
    instantiateSingleBackendAdapter(const CreationContext& xContext)
{
    return *new SingleBackendAdapter(xContext) ;
}
//------------------------------------------------------------------------------

static const rtl::OUString kImplementationName(
                                RTL_CONSTASCII_USTRINGPARAM(kImplementation)) ;

rtl::OUString SAL_CALL
    SingleBackendAdapter::getName(void)
{
    return kImplementationName ;
}
//------------------------------------------------------------------------------

rtl::OUString SAL_CALL
    SingleBackendAdapter::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::supportsService(const rtl::OUString& aServiceName)
        throw (uno::RuntimeException)
{
    return  ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName) ;
}
//------------------------------------------------------------------------------

uno::Sequence<rtl::OUString> SAL_CALL
    SingleBackendAdapter::getServices()
{
    return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
}
//------------------------------------------------------------------------------

uno::Sequence<rtl::OUString> SAL_CALL
    SingleBackendAdapter::getSupportedServiceNames(void)
        throw (uno::RuntimeException)
{
    return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
}
//------------------------------------------------------------------------------

} } // configmgr.backend

<commit_msg>INTEGRATION: CWS ooo19126 (1.10.74); FILE MERGED 2005/09/05 17:04:05 rt 1.10.74.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: singlebackendadapter.cxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-08 03:34:20 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_
#include "singlebackendadapter.hxx"
#endif // CONFIGMGR_BACKEND_SINGLEBACKENDADAPTER_HXX_

#ifndef CONFIGMGR_API_FACTORY_HXX_
#include "confapifactory.hxx"
#endif // CONFIGMGR_API_FACTORY_HXX_

#ifndef CONFIGMGR_SERVICEINFOHELPER_HXX_
#include "serviceinfohelper.hxx"
#endif // CONFIGMGR_SERVICEINFOHELPER_HXX_

#ifndef _COM_SUN_STAR_CONFIGURATION_BACKEND_XMULTILAYERSTRATUM_HPP_
#include <com/sun/star/configuration/backend/XMultiLayerStratum.hpp>
#endif
#ifndef _COM_SUN_STAR_CONFIGURATION_CANNOTLOADCONFIGURATIONEXCEPTION_HPP_
#include <com/sun/star/configuration/CannotLoadConfigurationException.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_DISPOSEDEXCEPTION_HPP_
#include <com/sun/star/lang/DisposedException.hpp>
#endif
namespace configmgr { namespace backend {

//==============================================================================

SingleBackendAdapter::SingleBackendAdapter(
        const uno::Reference<uno::XComponentContext>& xContext)
        : BackendBase(mMutex), mFactory(xContext->getServiceManager(),uno::UNO_QUERY) {
}
//------------------------------------------------------------------------------

SingleBackendAdapter::~SingleBackendAdapter(void) {}
//------------------------------------------------------------------------------

void SAL_CALL SingleBackendAdapter::initialize(
        const uno::Sequence<uno::Any>& aParameters)
    throw (uno::RuntimeException, uno::Exception) {

    uno::Any const * const pParams = aParameters.getConstArray();
    sal_Int32 nCount = aParameters.getLength();

    for (sal_Int32 ix = 0; ix < nCount; ++ix)
    {
        if (pParams[ix] >>= mBackend) break;
    }

    if (!mBackend.is())
    {
        throw com::sun::star::configuration::CannotLoadConfigurationException(
            OUString::createFromAscii("Online SingleBackend Adapter: Cannot operate without real (Single)Backend"),
            *this);
    }
}
//------------------------------------------------------------------------------
static inline OUString getSingleLayerDummyEntity()
{ return OUString(RTL_CONSTASCII_USTRINGPARAM("*")); }
//------------------------------------------------------------------------------
bool SingleBackendAdapter::checkOkState()
{
    if (!mBackend.is())
    {
        if(rBHelper.bDisposed)
        {
            throw lang::DisposedException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Backend already disposed")),*this);
        }
        else
        {
            throw backenduno::BackendAccessException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this,uno::Any() );
        }
    }
    return true;
}

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

// XBackendEntities
rtl::OUString SAL_CALL
    SingleBackendAdapter::getOwnerEntity(  )
        throw (uno::RuntimeException)
{
    if (mBackend.is())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );

        return xEntities->getOwnerEntity();
    }
    else
    {
        throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this);
    }
}
//------------------------------------------------------------------------------

rtl::OUString SAL_CALL
    SingleBackendAdapter::getAdminEntity(  )
        throw (uno::RuntimeException)
{
    if (mBackend.is())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->getAdminEntity();
    }
    else
    {
        throw uno::RuntimeException(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
            "SingleBackendAdapter: Object was never Initialised")),*this);
    }
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::supportsEntity( const rtl::OUString& aEntity )
    throw (backenduno::BackendAccessException, uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->supportsEntity(aEntity);
    }
    return false;
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::isEqualEntity( const rtl::OUString& aEntity, const rtl::OUString& aOtherEntity )
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XBackendEntities > xEntities( mBackend, uno::UNO_REF_QUERY_THROW );
        return xEntities->isEqualEntity(aEntity,aOtherEntity);
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XSchema> SAL_CALL
    SingleBackendAdapter::getComponentSchema(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return mBackend->getComponentSchema(aComponent) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
    SingleBackendAdapter::listOwnLayers(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return listLayers(aComponent, this->getOwnerEntity()) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XUpdateHandler> SAL_CALL
    SingleBackendAdapter::getOwnUpdateHandler(const rtl::OUString& aComponent)
        throw (backenduno::BackendAccessException,
                lang::NoSupportException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        return getUpdateHandler(aComponent, this->getOwnerEntity()) ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Sequence<uno::Reference<backenduno::XLayer> > SAL_CALL
    SingleBackendAdapter::listLayers(const rtl::OUString& aComponent,
                                          const rtl::OUString& aEntity)
        throw (backenduno::BackendAccessException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );

        uno::Sequence<uno::Reference<backenduno::XLayer> > retCode =
            xBackend->getLayers(xBackend->listLayerIds(aComponent, aEntity),
                            rtl::OUString()) ;

        // There might be non-existent layers in the list if there's no
        // actual data associated to a given layer id. Hence we have to
        // compress the list.
        sal_Int32 maxLayer = 0 ;

        for (sal_Int32 i = 0 ; i < retCode.getLength() ; ++ i)
        {
            if (retCode [i].is())
            {
                if (i != maxLayer) { retCode [maxLayer] = retCode [i] ; }
                ++ maxLayer ;
            }
        }
        retCode.realloc(maxLayer) ;
        return retCode ;
    }
    return false;
}
//------------------------------------------------------------------------------

uno::Reference<backenduno::XUpdateHandler> SAL_CALL
    SingleBackendAdapter::getUpdateHandler(const rtl::OUString& aComponent,
                                                const rtl::OUString& aEntity)
        throw (backenduno::BackendAccessException,
                lang::NoSupportException,
                lang::IllegalArgumentException,
                uno::RuntimeException)
{
    if (checkOkState())
    {
        uno::Reference< backenduno::XMultiLayerStratum > xBackend( mBackend, uno::UNO_REF_QUERY_THROW );

        uno::Sequence<uno::Any> arguments(1) ;

        arguments [0] <<= xBackend->getUpdatableLayer(
                                        xBackend->getUpdateLayerId(aComponent,
                                                                   aEntity)) ;
        uno::Reference< uno::XInterface > xHandler;
        try
        {
            const rtl::OUString kUpdateMerger(RTL_CONSTASCII_USTRINGPARAM(
                "com.sun.star.configuration.backend.LayerUpdateMerger")) ;

            xHandler = mFactory->createInstanceWithArguments(kUpdateMerger, arguments);
        }
        catch (uno::RuntimeException & )
        {throw;}
        catch (uno::Exception & e)
        {
            const rtl::OUString sMessage(RTL_CONSTASCII_USTRINGPARAM(
                "Configuration SingleBackendAdapter: Cannot create UpdateMerger - error message: ")) ;
            throw uno::RuntimeException(sMessage.concat(e.Message),*this);
        }

        return uno::Reference<backenduno::XUpdateHandler>(xHandler, uno::UNO_REF_QUERY_THROW) ;
    }
    return false;
}
//------------------------------------------------------------------------------

static const sal_Char * const kBackendService = "com.sun.star.configuration.backend.Backend" ;
static const sal_Char * const kAdapterService = "com.sun.star.configuration.backend.BackendAdapter" ;
static const sal_Char * const kOnlineService  = "com.sun.star.configuration.backend.OnlineBackend" ;

static const sal_Char * const kImplementation =
                "com.sun.star.comp.configuration.backend.SingleBackendAdapter" ;

static const AsciiServiceName kServiceNames [] =
{
    kOnlineService,
    kAdapterService,
    0,
    kBackendService,
    0
} ;
static const ServiceImplementationInfo kServiceInfo =
{
    kImplementation,
    kServiceNames,
    kServiceNames + 3
} ;

const ServiceRegistrationInfo *getSingleBackendAdapterServiceInfo()
{
    return getRegistrationInfo(&kServiceInfo) ;
}

uno::Reference<uno::XInterface> SAL_CALL
    instantiateSingleBackendAdapter(const CreationContext& xContext)
{
    return *new SingleBackendAdapter(xContext) ;
}
//------------------------------------------------------------------------------

static const rtl::OUString kImplementationName(
                                RTL_CONSTASCII_USTRINGPARAM(kImplementation)) ;

rtl::OUString SAL_CALL
    SingleBackendAdapter::getName(void)
{
    return kImplementationName ;
}
//------------------------------------------------------------------------------

rtl::OUString SAL_CALL
    SingleBackendAdapter::getImplementationName(void)
        throw (uno::RuntimeException)
{
    return ServiceInfoHelper(&kServiceInfo).getImplementationName() ;
}
//------------------------------------------------------------------------------

sal_Bool SAL_CALL
    SingleBackendAdapter::supportsService(const rtl::OUString& aServiceName)
        throw (uno::RuntimeException)
{
    return  ServiceInfoHelper(&kServiceInfo).supportsService(aServiceName) ;
}
//------------------------------------------------------------------------------

uno::Sequence<rtl::OUString> SAL_CALL
    SingleBackendAdapter::getServices()
{
    return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
}
//------------------------------------------------------------------------------

uno::Sequence<rtl::OUString> SAL_CALL
    SingleBackendAdapter::getSupportedServiceNames(void)
        throw (uno::RuntimeException)
{
    return ServiceInfoHelper(&kServiceInfo).getSupportedServiceNames() ;
}
//------------------------------------------------------------------------------

} } // configmgr.backend

<|endoftext|>