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

#include "asmith/serial/xml.hpp"

namespace asmith { namespace serial {

	//! \todo Remove illegal characters in xml

	static void xml_write_internal(const value& aType, std::ostream& aStream) {
		const value::type tBuf = aType.get_type();

		switch(tBuf) {
		case value::NULL_T:
			aStream << "null";
			break;
		case value::BOOl_T:
			aStream << (aType.get_bool() ? "true" : "false");
			break;
		case value::CHAR_T:
			aStream << aType.get_char() ;
			break;
		case value::NUMBER_T:
			aStream << aType.get_number();
			break;
		case value::STRING_T:
			aStream << aType.get_string();
			break;
		case value::ARRAY_T:
			throw std::runtime_error("xml_format : Cannot write array as internal value");
			break;
		case value::OBJECT_T:
			throw std::runtime_error("xml_format : Cannot write object as internal value");
			break;
		default:
			throw std::runtime_error("xml_format : Invalid serial type");
			break;
		}
	}

	static void xml_write_element(const char* const aName, const value& aType, std::ostream& aStream) {
		bool closeTag = true;
		aStream << "<" << aName;
		const value::type tBuf = aType.get_type();

		switch(tBuf) {
		case value::NULL_T:
			aStream << "/>";
			closeTag = false;
			break;
		case value::BOOl_T:
			aStream << ">";
			aStream << (aType.get_bool() ? "true" : "false");
			break;
		case value::CHAR_T:
			aStream << ">";
			aStream << aType.get_char();
			break;
		case value::NUMBER_T:
			aStream << ">";
			aStream << aType.get_number();
			break;
		case value::STRING_T:
			aStream << ">";
			aStream << aType.get_string();
			break;
		case value::ARRAY_T:
			aStream << ">";
			{
				const value::array_t tmp = aType.get_array();
				const size_t s = tmp.size();
				for(size_t i = 0; i < s; ++i) {
					xml_write_element(std::to_string(i).c_str(), tmp[i], aStream);
				}
			}
			break;
		case value::OBJECT_T:
			aStream << ">";
			{
				const value::object_t tmp = aType.get_object();
				const size_t s = tmp.size();

				for(const auto& v : tmp) {
					const value::type t = v.second.get_type();
					if(t != value::ARRAY_T && t != value::OBJECT_T) {
						aStream << ' ' << v.first << '=' << '"';
						xml_write_internal(v.second, aStream);
						aStream << '"';
					}
				}

				aStream << ">";

				for (const auto& v : tmp) {
					const value::type t = v.second.get_type();
					if(t == value::ARRAY_T || t == value::OBJECT_T) {
						xml_write_element(v.first.c_str(), v.second, aStream);
					}
				}
			}
			break;
		default:
			throw std::runtime_error("xml_format : Invalid serial type");
			break;
		}
		if(closeTag) aStream << "</" << aName << ">";
	}

	void xml_format::write_serial(const value& aType, std::ostream& aStream) {
		xml_write_element("xml", aType, aStream);
	}

	value xml_format::read_serial(std::istream& aStream) {
		//! \todo Implement
		return value();
	}
}}<commit_msg>Fixed bug in XML object write<commit_after>//	Copyright 2017 Adam Smith
//	Licensed under the Apache License, Version 2.0 (the "License");
//	you may not use this file except in compliance with the License.
//	You may obtain a copy of the License at
//
//	http://www.apache.org/licenses/LICENSE-2.0
//
//	Unless required by applicable law or agreed to in writing, software
//	distributed under the License is distributed on an "AS IS" BASIS,
//	WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//	See the License for the specific language governing permissions and
//	limitations under the License.

#include "asmith/serial/xml.hpp"

namespace asmith { namespace serial {

	//! \todo Remove illegal characters in xml

	static void xml_write_internal(const value& aType, std::ostream& aStream) {
		const value::type tBuf = aType.get_type();

		switch(tBuf) {
		case value::NULL_T:
			aStream << "null";
			break;
		case value::BOOl_T:
			aStream << (aType.get_bool() ? "true" : "false");
			break;
		case value::CHAR_T:
			aStream << aType.get_char() ;
			break;
		case value::NUMBER_T:
			aStream << aType.get_number();
			break;
		case value::STRING_T:
			aStream << aType.get_string();
			break;
		case value::ARRAY_T:
			throw std::runtime_error("xml_format : Cannot write array as internal value");
			break;
		case value::OBJECT_T:
			throw std::runtime_error("xml_format : Cannot write object as internal value");
			break;
		default:
			throw std::runtime_error("xml_format : Invalid serial type");
			break;
		}
	}

	static void xml_write_element(const char* const aName, const value& aType, std::ostream& aStream) {
		bool closeTag = true;
		aStream << "<" << aName;
		const value::type tBuf = aType.get_type();

		switch(tBuf) {
		case value::NULL_T:
			aStream << "/>";
			closeTag = false;
			break;
		case value::BOOl_T:
			aStream << ">";
			aStream << (aType.get_bool() ? "true" : "false");
			break;
		case value::CHAR_T:
			aStream << ">";
			aStream << aType.get_char();
			break;
		case value::NUMBER_T:
			aStream << ">";
			aStream << aType.get_number();
			break;
		case value::STRING_T:
			aStream << ">";
			aStream << aType.get_string();
			break;
		case value::ARRAY_T:
			aStream << ">";
			{
				const value::array_t tmp = aType.get_array();
				const size_t s = tmp.size();
				for(size_t i = 0; i < s; ++i) {
					xml_write_element(std::to_string(i).c_str(), tmp[i], aStream);
				}
			}
			break;
		case value::OBJECT_T:
			{
				const value::object_t tmp = aType.get_object();
				const size_t s = tmp.size();

				for(const auto& v : tmp) {
					const value::type t = v.second.get_type();
					if(t != value::ARRAY_T && t != value::OBJECT_T) {
						aStream << ' ' << v.first << '=' << '"';
						xml_write_internal(v.second, aStream);
						aStream << '"';
					}
				}

				aStream << ">";

				for (const auto& v : tmp) {
					const value::type t = v.second.get_type();
					if(t == value::ARRAY_T || t == value::OBJECT_T) {
						xml_write_element(v.first.c_str(), v.second, aStream);
					}
				}
			}
			break;
		default:
			throw std::runtime_error("xml_format : Invalid serial type");
			break;
		}
		if(closeTag) aStream << "</" << aName << ">";
	}

	void xml_format::write_serial(const value& aType, std::ostream& aStream) {
		xml_write_element("xml", aType, aStream);
	}

	value xml_format::read_serial(std::istream& aStream) {
		//! \todo Implement
		return value();
	}
}}<|endoftext|>


<commit_before>#include "../mtlpp.hpp"
#include <stdio.h>

int main()
{
    mtlpp::Device device = mtlpp::Device::CreateSystemDefaultDevice();
    assert(device);

    const char shadersSrc[] = R"""(
        #include <metal_stdlib>
        using namespace metal;

        kernel void sqr(
            const device float *vIn [[ buffer(0) ]],
            device float *vOut [[ buffer(1) ]],
            uint id[[ thread_position_in_grid ]])
        {
            vOut[id] = vIn[id] * vIn[id];
        }
    )""";

    mtlpp::Library library = device.NewLibrary(shadersSrc, mtlpp::CompileOptions(), nullptr);
    assert(library);
    mtlpp::Function sqrFunc = library.NewFunction("sqr");
    assert(sqrFunc);

    mtlpp::ComputePipelineState computePipelineState = device.NewComputePipelineState(sqrFunc, nullptr);
    assert(computePipelineState);

    const uint32_t inDataCount = 8;
    const float inData[inDataCount] = { 0.0f, 1.0f, 2.0f, 10.0f, 11.0f, 12.0f, 20, 21 };

    mtlpp::Buffer inBuffer = device.NewBuffer(inData, sizeof(inData), mtlpp::ResourceOptions::CpuCacheModeDefaultCache);
    assert(inBuffer);

    mtlpp::Buffer outBuffer = device.NewBuffer(sizeof(inData), mtlpp::ResourceOptions::CpuCacheModeDefaultCache);
    assert(outBuffer);

    mtlpp::CommandQueue commandQueue = device.NewCommandQueue();
    assert(commandQueue);
    mtlpp::CommandBuffer commandBuffer = commandQueue.CommandBuffer();
    assert(commandBuffer);

    mtlpp::ComputeCommandEncoder commandEncoder = commandBuffer.ComputeCommandEncoder();
    commandEncoder.SetBuffer(inBuffer, 0, 0);
    commandEncoder.SetBuffer(outBuffer, 0, 1);
    commandEncoder.SetComputePipelineState(computePipelineState);

    commandEncoder.DispatchThreadgroups(
        mtlpp::Size(1, 1, 1),
        mtlpp::Size(inDataCount, 1, 1));

    commandEncoder.EndEncoding();
    commandBuffer.Commit();
    commandBuffer.WaitUntilCompleted();

    float* outData = static_cast<float*>(outBuffer.GetContents());
    for (uint32_t i=0; i<inDataCount; i++)
        printf("sqr(%g) = %g\n", inData[i], outData[i]);

    return 0;
}

<commit_msg>Added multiple compute dispatches.<commit_after>#include "../mtlpp.hpp"
#include <stdio.h>

int main()
{
    mtlpp::Device device = mtlpp::Device::CreateSystemDefaultDevice();
    assert(device);

    const char shadersSrc[] = R"""(
        #include <metal_stdlib>
        using namespace metal;

        kernel void sqr(
            const device float *vIn [[ buffer(0) ]],
            device float *vOut [[ buffer(1) ]],
            uint id[[ thread_position_in_grid ]])
        {
            vOut[id] = vIn[id] * vIn[id];
        }
    )""";

    mtlpp::Library library = device.NewLibrary(shadersSrc, mtlpp::CompileOptions(), nullptr);
    assert(library);
    mtlpp::Function sqrFunc = library.NewFunction("sqr");
    assert(sqrFunc);

    mtlpp::ComputePipelineState computePipelineState = device.NewComputePipelineState(sqrFunc, nullptr);
    assert(computePipelineState);

    const uint32_t dataCount = 6;

    mtlpp::Buffer inBuffer = device.NewBuffer(sizeof(float) * dataCount, mtlpp::ResourceOptions::CpuCacheModeDefaultCache);
    assert(inBuffer);

    mtlpp::Buffer outBuffer = device.NewBuffer(sizeof(float) * dataCount, mtlpp::ResourceOptions::CpuCacheModeDefaultCache);
    assert(outBuffer);

    for (uint32_t i=0; i<4; i++)
    {
        // update input data
        {
            float* inData = static_cast<float*>(inBuffer.GetContents());
            for (uint32_t j=0; j<dataCount; j++)
                inData[j] = 10 * i + j;
            inBuffer.DidModify(ns::Range(0, sizeof(float) * dataCount));
        }

        mtlpp::CommandQueue commandQueue = device.NewCommandQueue();
        assert(commandQueue);
        mtlpp::CommandBuffer commandBuffer = commandQueue.CommandBuffer();
        assert(commandBuffer);

        mtlpp::ComputeCommandEncoder commandEncoder = commandBuffer.ComputeCommandEncoder();
        commandEncoder.SetBuffer(inBuffer, 0, 0);
        commandEncoder.SetBuffer(outBuffer, 0, 1);
        commandEncoder.SetComputePipelineState(computePipelineState);

        commandEncoder.DispatchThreadgroups(
            mtlpp::Size(1, 1, 1),
            mtlpp::Size(dataCount, 1, 1));

        commandEncoder.EndEncoding();
        commandBuffer.Commit();
        commandBuffer.WaitUntilCompleted();

        // read the data
        {
            float* inData = static_cast<float*>(inBuffer.GetContents());
            float* outData = static_cast<float*>(outBuffer.GetContents());
            for (uint32_t j=0; j<dataCount; j++)
                printf("sqr(%g) = %g\n", inData[j], outData[j]);
        }
    }

    return 0;
}

<|endoftext|>


<commit_before><commit_msg>Jenkins: Format fixes<commit_after><|endoftext|>


<commit_before>/*
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Soumyajit De
 */

#include <shogun/lib/common.h>

#ifdef HAVE_EIGEN3
#include <shogun/lib/Time.h>
#include <shogun/lib/SGVector.h>
#include <shogun/lib/SGSparseMatrix.h>
#include <shogun/lib/SGSparseVector.h>
#include <shogun/mathematics/Math.h>
#include <shogun/mathematics/eigen3.h>

using namespace shogun;
using namespace Eigen;

SGVector<float64_t> sg_m_apply(SGSparseMatrix<float64_t> m, SGVector<float64_t> v)
{
	SGVector<float64_t> r(v.vlen);
	ASSERT(v.vlen==m.num_vectors);
#pragma omp parallel for
	for (index_t i=0; i<m.num_vectors; ++i)
		r[i]=m[i].dense_dot(1.0, v.vector, v.vlen, 0.0);

	return r;
}

int main(int argc, char** argv)
{
	init_shogun_with_defaults();
	//sg_io->set_loglevel(MSG_GCDEBUG);

	const index_t n=100;
	const index_t times=5;
	const index_t size=1000000;
	SGVector<float64_t> v(size);
	v.set_const(1.0);
	Map<VectorXd> map_v(v.vector, v.vlen);
	CTime time;

	SG_SPRINT("time\tshogun (s)\teigen3 (s)\n\n");
	for (index_t t=0; t<times; ++t)
	{
//#ifdef RUN_SHOGUN
		SGSparseMatrix<float64_t> sg_m(size, size);
		typedef SGSparseVectorEntry<float64_t> Entry;
		SGSparseVector<float64_t> *vec=SG_MALLOC(SGSparseVector<float64_t>, size);

		// for first row
		Entry *first=SG_MALLOC(Entry, size);
		// the digonal index for row #1
		first[0].feat_index=0;
		first[0].entry=1.836593;
		for (index_t i=1; i<size; ++i)
		{
			// fill the index for row #1
			first[i].feat_index=i;
			first[i].entry=0.02;
		}
		vec[0].features=first;
		vec[0].num_feat_entries=size;
		sg_m[0]=vec[0].get();

		// fill the rest of the rows
		Entry** rest=SG_MALLOC(Entry*, size-1);
		for (index_t i=0; i<size-1; ++i)
		{
			// the first col
			rest[i]=SG_MALLOC(Entry, 2);
			rest[i][0].feat_index=0;
			rest[i][0].entry=0.01;

			// the diagonal element
			rest[i][1].feat_index=i+1;
			rest[i][1].entry=1.836593;

			vec[i+1].features=rest[i];
			vec[i+1].num_feat_entries=2;

			sg_m[i+1]=vec[i+1].get();
		}
		SGVector<float64_t> r(size);

		// sg starts
		time.start();
		for (index_t i=0; i<n; ++i)
			r=sg_m_apply(sg_m, v);
		float64_t sg_time = time.cur_time_diff();

		Map<VectorXd> map_r(r.vector, r.vlen);
		float64_t sg_norm=map_r.norm();

//#endif // RUN_SHOGUN

//#ifdef RUN_EIGEN
		const SparseMatrix<float64_t> &eig_m=EigenSparseUtil<float64_t>::toEigenSparse(sg_m);
		VectorXd eig_r(size);

		// eigen3 starts
		time.start();
		for (index_t i=0; i<n; ++i)
			eig_r=eig_m*map_v;

		float64_t eig_time = time.cur_time_diff();
		float64_t eig_norm=eig_r.norm();
//#endif // RUN_EIGEN

		SG_SPRINT("%d\t%lf\t%lf\n", t, sg_time, eig_time);
		//ASSERT(sg_time>eig_time);
		ASSERT(CMath::abs(sg_norm-eig_norm)<=CMath::MACHINE_EPSILON)

		SG_FREE(vec);
		SG_FREE(rest);
	}

	exit_shogun();

	return 0;
}
#endif // HAVE_EIGEN3
<commit_msg>add phtread based sparse test bench<commit_after>/*
 * 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 3 of the License, or
 * (at your option) any later version.
 *
 * Written (W) 2013 Soumyajit De
 */

#include <shogun/lib/common.h>

#ifdef HAVE_EIGEN3
#include <shogun/lib/Time.h>
#include <shogun/lib/SGVector.h>
#include <shogun/lib/SGSparseMatrix.h>
#include <shogun/lib/SGSparseVector.h>
#include <shogun/mathematics/Math.h>
#include <shogun/mathematics/eigen3.h>
#include <pthread.h>

using namespace shogun;
using namespace Eigen;

struct APPLY_THREAD_PARAM
{
	int32_t start;
	int32_t stop;
	float64_t* result;
	float64_t* vec;
	int32_t len;
	SGSparseVector<float64_t>* sm;
};

int32_t get_nnz(SGSparseMatrix<float64_t> m)
{

	int32_t nnz=0;
	int32_t n=m.num_vectors;

	for (int i=0; i<n; i++)
	{
		nnz+=m[i].num_feat_entries;
	}
	return nnz;
}

static void* dot_helper(void* p)
{
	APPLY_THREAD_PARAM* par=(APPLY_THREAD_PARAM*) p;
	float64_t* r = par->result;
	SGSparseVector<float64_t>* m=par->sm;
	float64_t* vec = par->vec;
	int32_t len = par->len;
	int32_t start = par->start;
	int32_t stop = par->stop;

	for (index_t i=start; i<stop; ++i)
		r[i]=m[i].dense_dot(1.0, vec, len, 0.0);
}

SGVector<float64_t> sg_m_apply(SGSparseMatrix<float64_t> m, SGVector<float64_t> v)
{
	SGVector<float64_t> r(v.vlen);
	ASSERT(v.vlen==m.num_vectors);

	int num_threads=8;
	pthread_t* threads = SG_MALLOC(pthread_t, num_threads-1);
	APPLY_THREAD_PARAM* params = SG_MALLOC(APPLY_THREAD_PARAM, num_threads);
	int32_t step= m.num_vectors/num_threads;

	int32_t start=0;
	int32_t stop=m.num_vectors;
	int32_t t;

	for (t=0; t<num_threads-1; t++)
	{
		params[t].start = start+t*step;
		params[t].stop = start+(t+1)*step;
		params[t].result = r.vector;
		params[t].sm=m.sparse_matrix;
		params[t].vec=v.vector;
		params[t].len=v.vlen;
		pthread_create(&threads[t], NULL,
				dot_helper, (void*)&params[t]);
	}

	params[t].start = start+t*step;
	params[t].stop = stop;
	params[t].result = r.vector;
	params[t].sm=m.sparse_matrix;
	params[t].vec=v.vector;
	params[t].len=v.vlen;
	dot_helper((void*) &params[t]);

	for (t=0; t<num_threads-1; t++)
		pthread_join(threads[t], NULL);

	SG_FREE(params);
	SG_FREE(threads);

	return r;
}

int main(int argc, char** argv)
{
	Eigen::initParallel();
	init_shogun_with_defaults();
	//sg_io->set_loglevel(MSG_GCDEBUG);

	const index_t n=100;
	const index_t times=5;
	const index_t size=1000000;
	SGVector<float64_t> v(size);
	v.set_const(1.0);
	Map<VectorXd> map_v(v.vector, v.vlen);
	CTime time;
	CMath::init_random(17);

	SG_SPRINT("time\tshogun (s)\teigen3 (s)\n\n");
	for (index_t t=0; t<times; ++t)
	{
//#ifdef RUN_SHOGUN
		SGSparseMatrix<float64_t> sg_m(size, size);
		typedef SGSparseVectorEntry<float64_t> Entry;
		SGSparseVector<float64_t> *vec=SG_MALLOC(SGSparseVector<float64_t>, size);

		// for first row
		Entry *first=SG_MALLOC(Entry, size);
		// the digonal index for row #1
		first[0].feat_index=0;
		first[0].entry=1.836593;
		for (index_t i=1; i<size; ++i)
		{
			// fill the index for row #1
			first[i].feat_index=i;
			first[i].entry=0.02;
		}
		vec[0].features=first;
		vec[0].num_feat_entries=size;
		sg_m[0]=vec[0].get();

		// fill the rest of the rows
		Entry** rest=SG_MALLOC(Entry*, size-1);
		for (index_t i=0; i<size-1; ++i)
		{
			int num=40;
			// the first col
			rest[i]=SG_MALLOC(Entry, num);

			for (int j=0; j<i && j<num; j++)
			{
				rest[i][j].feat_index=j;
				rest[i][j].entry=0.01+j;
			}

			if (i>num)
			{
				//// the diagonal element
				rest[i][num-1].feat_index=i+1;
				rest[i][num-1].entry=1.836593;
			}

			vec[i+1].features=rest[i];
			vec[i+1].num_feat_entries=num;

			sg_m[i+1]=vec[i+1].get();
		}
		SGVector<float64_t> r(size);

		SG_SPRINT("nnz=%d\n", get_nnz(sg_m));

		// sg starts
		time.start();
		for (index_t i=0; i<n; ++i)
			r=sg_m_apply(sg_m, v);
		float64_t sg_time = time.cur_time_diff();

		Map<VectorXd> map_r(r.vector, r.vlen);
		float64_t sg_norm=map_r.norm();

//#endif // RUN_SHOGUN

//#ifdef RUN_EIGEN
		const SparseMatrix<float64_t> &eig_m=EigenSparseUtil<float64_t>::toEigenSparse(sg_m);
		VectorXd eig_r(size);

		// eigen3 starts
		time.start();
		for (index_t i=0; i<n; ++i)
			eig_r=eig_m*map_v;

		float64_t eig_time = time.cur_time_diff();
		float64_t eig_norm=eig_r.norm();
//#endif // RUN_EIGEN

		SG_SPRINT("%d\t%lf\t%lf\n", t, sg_time, eig_time);
		//ASSERT(sg_time>eig_time);
		ASSERT(CMath::abs(sg_norm-eig_norm)<=CMath::MACHINE_EPSILON)

		SG_FREE(vec);
		SG_FREE(rest);
	}

	exit_shogun();

	return 0;
}
#endif // HAVE_EIGEN3
<|endoftext|>


<commit_before>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2002 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdio.h>
#include <prsystem.h>

#include <vpr/md/NSPR/IO/Socket/InetAddrNSPR.h>
#include <vpr/Util/Error.h>

namespace vpr
{

const InetAddrNSPR InetAddrNSPR::AnyAddr;      // Default constructor defaults to ANY addr

vpr::ReturnStatus InetAddrNSPR::getLocalHost (vpr::InetAddrNSPR& host_addr)
{
   vpr::ReturnStatus status(vpr::ReturnStatus::Fail);
   char local_host_name[257];

   if ( PR_GetSystemInfo(PR_SI_HOSTNAME, local_host_name, 256) == PR_SUCCESS )
   {
      host_addr.setAddress(std::string(local_host_name), 0);
      status.setCode(vpr::ReturnStatus::Succeed);
   }

   return status;
}

// ----------------------------------------------------------------------------
// Set the address for this object using the given address.  It must be of the
// form <address>:<port> where <address> can be a hostname or a dotted-decimal
// IP address.
// ----------------------------------------------------------------------------
vpr::ReturnStatus InetAddrNSPR::setAddress (const std::string& address)
{
   std::string::size_type pos;
   std::string host_addr, host_port;
   vpr::Uint16 port;
   vpr::ReturnStatus retval;

   // Extract the address and the port number from the given string.
   pos       = address.find(":");
   host_addr = address.substr(0, pos);
   host_port = address.substr(pos + 1);
   port      = (vpr::Uint16) atoi(host_port.c_str());

   retval = lookupAddress(host_addr);
   setPort(port);
   setFamily(vpr::SocketTypes::INET);
   return retval;
}

// ----------------------------------------------------------------------------
// Get the protocol family of this address structure.
// ----------------------------------------------------------------------------
vpr::SocketTypes::Domain InetAddrNSPR::getFamily (void) const
{
   vpr::SocketTypes::Domain family;

   switch ( PR_NetAddrFamily(&mAddr) )
   {
      case PR_AF_INET:
         family = vpr::SocketTypes::INET;
         break;
      case PR_AF_LOCAL:
         family = vpr::SocketTypes::LOCAL;
         break;
      case PR_AF_INET6:
         family = vpr::SocketTypes::INET6;
         break;
   }

   return family;
}

// ----------------------------------------------------------------------------
// Set the protocol family of this address structure.
// ----------------------------------------------------------------------------
void InetAddrNSPR::setFamily (const vpr::SocketTypes::Domain family)
{
   switch ( family )
   {
      case vpr::SocketTypes::LOCAL:
         PR_NetAddrFamily(&mAddr) = PR_AF_LOCAL;
         break;
      case vpr::SocketTypes::INET:
         PR_NetAddrFamily(&mAddr) = PR_AF_INET;
         break;
      case vpr::SocketTypes::INET6:
         PR_NetAddrFamily(&mAddr) = PR_AF_INET6;
         break;
      default:
         fprintf(stderr,
                 "[vpr::InetAddrNSPR] ERROR: Unknown socket family value %d\n",
                 family);
         break;
   }
}

// ----------------------------------------------------------------------------
// Get the IP address associated with this structure as a human-readable
// string.
// ----------------------------------------------------------------------------
std::string InetAddrNSPR::getAddressString (void) const
{
   char ip_str[256];
   PR_NetAddrToString(&mAddr, ip_str, sizeof(PRNetAddr));
   std::string temp(ip_str);
   return temp;
}

std::string InetAddrNSPR::getHostname () const
{
   std::string hostname;
   char buffer[PR_NETDB_BUF_SIZE];
   PRStatus ret_status;
   PRHostEnt hostent;

   ret_status = PR_GetHostByAddr(&mAddr, buffer, sizeof(buffer), &hostent);

   if ( ret_status == PR_FAILURE )
   {
      vpr::Error::outputCurrentError(std::cerr, "[InetAddrNSPR::getHostname] Failed to get host by address");
      hostname = std::string("<hostname lookup failed>");
   }
   else
   {
      hostname = hostent.h_name;
   }

   return hostname;
}

std::vector<std::string> InetAddrNSPR::getHostnames () const
{
   std::vector<std::string> names;
   char buffer[PR_NETDB_BUF_SIZE];
   PRStatus ret_status;
   PRHostEnt hostent;

   ret_status = PR_GetHostByAddr(&mAddr, buffer, sizeof(buffer), &hostent);

   if ( ret_status != PR_FAILURE )
   {
      names.push_back(std::string(hostent.h_name));

      for ( char** ptr = hostent.h_aliases; *ptr != NULL; ptr++ )
      {
         names.push_back(std::string(*ptr));
      }
   }

   return names;
}

// ----------------------------------------------------------------------------
// Look up the address in mName and store the address in mAddr.
// ----------------------------------------------------------------------------
vpr::ReturnStatus InetAddrNSPR::lookupAddress (const std::string& address)
{
   vpr::ReturnStatus retval;
   PRStatus ret_status;
   PRHostEnt host_entry;
   char buffer[PR_NETDB_BUF_SIZE];

   ret_status = PR_GetHostByName(address.c_str(), buffer, sizeof(buffer),
                                 &host_entry);

   if ( ret_status == PR_FAILURE )
   {
      setAddressValue(0);           // Error on lookup, so zero the address
      std::string error_msg("[InetAddrNSPR::lookupAddress] Fail to look up host: ");
      error_msg += address;

      vpr::Error::outputCurrentError(std::cerr, error_msg);
      retval.setCode(ReturnStatus::Fail);
   }
   else
   {
      if ( PR_EnumerateHostEnt(0, &host_entry, 0, &mAddr) == -1 )
      {
         retval.setCode(ReturnStatus::Fail);
      }

      if ( retval.failure() )
      {
         vpr::Error::outputCurrentError(std::cerr, "[InetAddrNSPR::lookupAddress] Could not enumerate host entry");
      }
   }

   return retval;
}

} // End of vpr namespace
<commit_msg>Clear memory buffers before using<commit_after>/****************** <VPR heading BEGIN do not edit this line> *****************
 *
 * VR Juggler Portable Runtime
 *
 * Original Authors:
 *   Allen Bierbaum, Patrick Hartling, Kevin Meinert, Carolina Cruz-Neira
 *
 * -----------------------------------------------------------------
 * File:          $RCSfile$
 * Date modified: $Date$
 * Version:       $Revision$
 * -----------------------------------------------------------------
 *
 ****************** <VPR heading END do not edit this line> ******************/

/*************** <auto-copyright.pl BEGIN do not edit this line> **************
 *
 * VR Juggler is (C) Copyright 1998-2002 by Iowa State University
 *
 * Original Authors:
 *   Allen Bierbaum, Christopher Just,
 *   Patrick Hartling, Kevin Meinert,
 *   Carolina Cruz-Neira, Albert Baker
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library 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.
 *
 *************** <auto-copyright.pl END do not edit this line> ***************/

#include <vpr/vprConfig.h>

#include <stdio.h>
#include <prsystem.h>

#include <vpr/md/NSPR/IO/Socket/InetAddrNSPR.h>
#include <vpr/Util/Error.h>

namespace vpr
{

const InetAddrNSPR InetAddrNSPR::AnyAddr;      // Default constructor defaults to ANY addr

vpr::ReturnStatus InetAddrNSPR::getLocalHost (vpr::InetAddrNSPR& host_addr)
{
   vpr::ReturnStatus status(vpr::ReturnStatus::Fail);
   char local_host_name[257];
   memset(local_host_name, 0, 257);

   if ( PR_GetSystemInfo(PR_SI_HOSTNAME, local_host_name, 256) == PR_SUCCESS )
   {
      host_addr.setAddress(std::string(local_host_name), 0);
      status.setCode(vpr::ReturnStatus::Succeed);
   }

   return status;
}

// ----------------------------------------------------------------------------
// Set the address for this object using the given address.  It must be of the
// form <address>:<port> where <address> can be a hostname or a dotted-decimal
// IP address.
// ----------------------------------------------------------------------------
vpr::ReturnStatus InetAddrNSPR::setAddress (const std::string& address)
{
   std::string::size_type pos;
   std::string host_addr, host_port;
   vpr::Uint16 port;
   vpr::ReturnStatus retval;

   // Extract the address and the port number from the given string.
   pos       = address.find(":");
   host_addr = address.substr(0, pos);
   host_port = address.substr(pos + 1);
   port      = (vpr::Uint16) atoi(host_port.c_str());

   retval = lookupAddress(host_addr);
   setPort(port);
   setFamily(vpr::SocketTypes::INET);
   return retval;
}

// ----------------------------------------------------------------------------
// Get the protocol family of this address structure.
// ----------------------------------------------------------------------------
vpr::SocketTypes::Domain InetAddrNSPR::getFamily (void) const
{
   vpr::SocketTypes::Domain family;

   switch ( PR_NetAddrFamily(&mAddr) )
   {
      case PR_AF_INET:
         family = vpr::SocketTypes::INET;
         break;
      case PR_AF_LOCAL:
         family = vpr::SocketTypes::LOCAL;
         break;
      case PR_AF_INET6:
         family = vpr::SocketTypes::INET6;
         break;
   }

   return family;
}

// ----------------------------------------------------------------------------
// Set the protocol family of this address structure.
// ----------------------------------------------------------------------------
void InetAddrNSPR::setFamily (const vpr::SocketTypes::Domain family)
{
   switch ( family )
   {
      case vpr::SocketTypes::LOCAL:
         PR_NetAddrFamily(&mAddr) = PR_AF_LOCAL;
         break;
      case vpr::SocketTypes::INET:
         PR_NetAddrFamily(&mAddr) = PR_AF_INET;
         break;
      case vpr::SocketTypes::INET6:
         PR_NetAddrFamily(&mAddr) = PR_AF_INET6;
         break;
      default:
         fprintf(stderr,
                 "[vpr::InetAddrNSPR] ERROR: Unknown socket family value %d\n",
                 family);
         break;
   }
}

// ----------------------------------------------------------------------------
// Get the IP address associated with this structure as a human-readable
// string.
// ----------------------------------------------------------------------------
std::string InetAddrNSPR::getAddressString (void) const
{
   char ip_str[256];
   memset(ip_str, 0, 256);
   PR_NetAddrToString(&mAddr, ip_str, sizeof(PRNetAddr));
   std::string temp(ip_str);
   return temp;
}

std::string InetAddrNSPR::getHostname () const
{
   std::string hostname;
   char buffer[PR_NETDB_BUF_SIZE];
   memset(buffer, 0, PR_NETDB_BUF_SIZE);
   PRStatus ret_status;
   PRHostEnt hostent;

   ret_status = PR_GetHostByAddr(&mAddr, buffer, sizeof(buffer), &hostent);

   if ( ret_status == PR_FAILURE )
   {
      vpr::Error::outputCurrentError(std::cerr, "[InetAddrNSPR::getHostname] Failed to get host by address");
      hostname = std::string("<hostname lookup failed>");
   }
   else
   {
      hostname = hostent.h_name;
   }

   return hostname;
}

std::vector<std::string> InetAddrNSPR::getHostnames () const
{
   std::vector<std::string> names;
   char buffer[PR_NETDB_BUF_SIZE];
   PRStatus ret_status;
   PRHostEnt hostent;

   ret_status = PR_GetHostByAddr(&mAddr, buffer, sizeof(buffer), &hostent);

   if ( ret_status != PR_FAILURE )
   {
      names.push_back(std::string(hostent.h_name));

      for ( char** ptr = hostent.h_aliases; *ptr != NULL; ptr++ )
      {
         names.push_back(std::string(*ptr));
      }
   }

   return names;
}

// ----------------------------------------------------------------------------
// Look up the address in mName and store the address in mAddr.
// ----------------------------------------------------------------------------
vpr::ReturnStatus InetAddrNSPR::lookupAddress (const std::string& address)
{
   vpr::ReturnStatus retval;
   PRStatus ret_status;
   PRHostEnt host_entry;
   char buffer[PR_NETDB_BUF_SIZE];

   ret_status = PR_GetHostByName(address.c_str(), buffer, sizeof(buffer),
                                 &host_entry);

   if ( ret_status == PR_FAILURE )
   {
      setAddressValue(0);           // Error on lookup, so zero the address
      std::string error_msg("[InetAddrNSPR::lookupAddress] Fail to look up host: ");
      error_msg += address;

      vpr::Error::outputCurrentError(std::cerr, error_msg);
      retval.setCode(ReturnStatus::Fail);
   }
   else
   {
      if ( PR_EnumerateHostEnt(0, &host_entry, 0, &mAddr) == -1 )
      {
         retval.setCode(ReturnStatus::Fail);
      }

      if ( retval.failure() )
      {
         vpr::Error::outputCurrentError(std::cerr, "[InetAddrNSPR::lookupAddress] Could not enumerate host entry");
      }
   }

   return retval;
}

} // End of vpr namespace
<|endoftext|>


<commit_before>#include <sstream>
// #include <iostream>
#include <cstdlib>

#include "iq-stanza.hpp"
#include "jabber-iq-auth.hpp"
#include "jabber-iq-register.hpp"
#include "jabber-iq-roster.hpp"

parseMap_t *IqStanza::m_namespaceParsers = NULL;

IqStanza::IqStanza(void) {
  if (NULL == m_namespaceParsers) {
    m_namespaceParsers = new parseMap_t;

    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:auth", JabberIqAuth::parse));
    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:register", JabberIqRegister::parse));
    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:roster", JabberIqRoster::parse));
  }
}

IqStanza::~IqStanza(void) {}

const std::string *IqStanza::renderIqStanza(const std::string *id, const std::string *name_space, const std::string &body) const {
  std::ostringstream query;

  query << "<query xmlns='" << *name_space << "'>" << body << "</query>";
  return renderStanza(id, "iq", query.str());
}

const std::string *IqStanza::render(const std::string *id) const {
  return renderStanza(id, "iq", "");
}

Stanza *IqStanza::parse(const JabberElementNode *root) {
  // If there are no children, then it's an iq stanza
  Stanza *result;
  std::string errorMessage;
  int error = 0;

  if (0 == root->m_children.size()) {
    result = new IqStanza();
  }
  else {
    const JabberElementNode *query_node = NULL;
    const std::string *name_space = NULL;
    for (jabberNodeList_t::const_iterator i=root->m_children.begin(); i != root->m_children.end(); ++i) {
      const JabberElementNode *node = dynamic_cast<JabberElementNode *>(*i);
      if ((NULL != node) && ("query" == node->m_name)) {
	query_node = node;
	for(xmlpp::SaxParser::AttributeList::const_iterator j = node->m_attributes.begin(); j != node->m_attributes.end(); ++j) {
	  if ("xmlns" == j->name) {
	    name_space = new std::string(j->value);
	  }
	}
      }
      if ((NULL != node) && ("error" == node->m_name)) {
	jabberNodeList_t::const_iterator j=node->m_children.begin();
	const JabberTextNode *text = dynamic_cast<JabberTextNode *>(*j);
	if (NULL != text) {
	  errorMessage = text->m_data;
	}

	for(xmlpp::SaxParser::AttributeList::const_iterator k = node->m_attributes.begin(); k != node->m_attributes.end(); ++k) {
	  if ("code" == k->name) {
	    error = strtod(k->value.c_str(), NULL);
	  }
	}
      }
    }
    if (NULL != name_space) {
      parseMap_t::iterator parser = m_namespaceParsers->find(*name_space);
      if (parser != m_namespaceParsers->end()) {
	result = (*parser->second)(query_node);
      }
      else {
	// std::cout << "I don't recognize the name space " << *name_space << std::endl;
	// SYZYGY -- log, I guess
	// I don't know the name space.  Log, I guess, and return a plain stanza
	result = new IqStanza();
      }
    }
  }
  if (NULL != result) {
    if ("" != errorMessage) {
      result->ErrorMessage(errorMessage);
      result->Error(error);
    }
    for(xmlpp::SaxParser::AttributeList::const_iterator i = root->m_attributes.begin(); i != root->m_attributes.end(); ++i) {
      if ("type" == i->name) {
	result->Type(i->value);
      }
      if ("id" == i->name) {
	result->Id(i->value);
      }
    }
  }
  return result;
}
<commit_msg>Make sure that the stanza is intialized to something because otherwise it might crap out because of a double-free.<commit_after>#include <sstream>
// #include <iostream>
#include <cstdlib>

#include "iq-stanza.hpp"
#include "jabber-iq-auth.hpp"
#include "jabber-iq-register.hpp"
#include "jabber-iq-roster.hpp"

parseMap_t *IqStanza::m_namespaceParsers = NULL;

IqStanza::IqStanza(void) {
  if (NULL == m_namespaceParsers) {
    m_namespaceParsers = new parseMap_t;

    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:auth", JabberIqAuth::parse));
    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:register", JabberIqRegister::parse));
    m_namespaceParsers->insert(parseMap_t::value_type("jabber:iq:roster", JabberIqRoster::parse));
  }
}

IqStanza::~IqStanza(void) {}

const std::string *IqStanza::renderIqStanza(const std::string *id, const std::string *name_space, const std::string &body) const {
  std::ostringstream query;

  query << "<query xmlns='" << *name_space << "'>" << body << "</query>";
  return renderStanza(id, "iq", query.str());
}

const std::string *IqStanza::render(const std::string *id) const {
  return renderStanza(id, "iq", "");
}

Stanza *IqStanza::parse(const JabberElementNode *root) {
  // If there are no children, then it's an iq stanza
  Stanza *result;
  std::string errorMessage;
  int error = 0;

  if (0 == root->m_children.size()) {
    result = new IqStanza();
  }
  else {
    const JabberElementNode *query_node = NULL;
    const std::string *name_space = NULL;
    for (jabberNodeList_t::const_iterator i=root->m_children.begin(); i != root->m_children.end(); ++i) {
      const JabberElementNode *node = dynamic_cast<JabberElementNode *>(*i);
      if ((NULL != node) && ("query" == node->m_name)) {
	query_node = node;
	for(xmlpp::SaxParser::AttributeList::const_iterator j = node->m_attributes.begin(); j != node->m_attributes.end(); ++j) {
	  if ("xmlns" == j->name) {
	    name_space = new std::string(j->value);
	  }
	}
      }
      if ((NULL != node) && ("error" == node->m_name)) {
	jabberNodeList_t::const_iterator j=node->m_children.begin();
	const JabberTextNode *text = dynamic_cast<JabberTextNode *>(*j);
	if (NULL != text) {
	  errorMessage = text->m_data;
	}

	for(xmlpp::SaxParser::AttributeList::const_iterator k = node->m_attributes.begin(); k != node->m_attributes.end(); ++k) {
	  if ("code" == k->name) {
	    error = strtod(k->value.c_str(), NULL);
	  }
	}
      }
    }
    if (NULL != name_space) {
      parseMap_t::iterator parser = m_namespaceParsers->find(*name_space);
      if (parser != m_namespaceParsers->end()) {
	result = (*parser->second)(query_node);
      }
      else {
	// std::cout << "I don't recognize the name space " << *name_space << std::endl;
	// SYZYGY -- log, I guess
	// I don't know the name space.  Log, I guess, and return a plain stanza
	result = new IqStanza();
      }
    }
    else {
      result = new IqStanza();
    }
  }
  if (NULL != result) {
    if ("" != errorMessage) {
      result->ErrorMessage(errorMessage);
      result->Error(error);
    }
    for(xmlpp::SaxParser::AttributeList::const_iterator i = root->m_attributes.begin(); i != root->m_attributes.end(); ++i) {
      if ("type" == i->name) {
	result->Type(i->value);
      }
      if ("id" == i->name) {
	result->Id(i->value);
      }
    }
  }
  return result;
}
<|endoftext|>


<commit_before>// Copyright (c) Arni Mar Jonsson.
// See LICENSE for details.

// The Python 2/3 compatability code was found in cporting.rst

#include "leveldb_ext.h"

static PyMethodDef leveldb_extension_methods[] =
{
	{ (char*)"RepairDB",  (PyCFunction)pyleveldb_repair_db,  METH_VARARGS, (char*)pyleveldb_repair_db_doc  },
	{ (char*)"DestroyDB", (PyCFunction)pyleveldb_destroy_db, METH_VARARGS, (char*)pyleveldb_destroy_db_doc },
	{NULL, NULL},
};

PyObject* leveldb_exception = 0;

#if PY_MAJOR_VERSION >= 3

struct leveldb_extension_state {
};

static int leveldb_extension_traverse(PyObject* m, visitproc visit, void* arg)
{
	return 0;
}

static int leveldb_extension_clear(PyObject* m)
{
	return 0;
}

static struct PyModuleDef leveldb_extension_def = {
	PyModuleDef_HEAD_INIT,
	"leveldb",
	NULL,
	sizeof(struct leveldb_extension_state),
	leveldb_extension_methods,
	NULL,
	leveldb_extension_traverse,
	leveldb_extension_clear,
	NULL
};

#define INITERROR return NULL

extern "C" PyObject* PyInit_leveldb(void)

#else

#define INITERROR return

extern "C" void initleveldb(void)

#endif
{
#if PY_MAJOR_VERSION >= 3
	PyObject* leveldb_module = PyModule_Create(&leveldb_extension_def);
#else
	PyObject* leveldb_module = Py_InitModule3((char*)"leveldb", leveldb_extension_methods, 0);
#endif

	if (leveldb_module == 0)
		INITERROR;

	// add custom exception
	leveldb_exception = PyErr_NewException((char*)"leveldb.LevelDBError", 0, 0);

	if (leveldb_exception == 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyModule_AddObject(leveldb_module, (char*)"LevelDBError", leveldb_exception) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyLevelDB_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyLevelDBSnapshot_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyWriteBatch_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	// add custom types to the different modules
	Py_INCREF(&PyLevelDB_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"LevelDB", (PyObject*)&PyLevelDB_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	Py_INCREF(&PyLevelDBSnapshot_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"Snapshot", (PyObject*)&PyLevelDBSnapshot_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	Py_INCREF(&PyWriteBatch_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"WriteBatch", (PyObject*)&PyWriteBatch_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	#if PY_MAJOR_VERSION >= 3
	return leveldb_module;
	#endif
}
<commit_msg>a potential fix for a locking bug<commit_after>// Copyright (c) Arni Mar Jonsson.
// See LICENSE for details.

// The Python 2/3 compatability code was found in cporting.rst

#include "leveldb_ext.h"

static PyMethodDef leveldb_extension_methods[] =
{
	{ (char*)"RepairDB",  (PyCFunction)pyleveldb_repair_db,  METH_VARARGS, (char*)pyleveldb_repair_db_doc  },
	{ (char*)"DestroyDB", (PyCFunction)pyleveldb_destroy_db, METH_VARARGS, (char*)pyleveldb_destroy_db_doc },
	{NULL, NULL},
};

PyObject* leveldb_exception = 0;

#if PY_MAJOR_VERSION >= 3

struct leveldb_extension_state {
};

static int leveldb_extension_traverse(PyObject* m, visitproc visit, void* arg)
{
	return 0;
}

static int leveldb_extension_clear(PyObject* m)
{
	return 0;
}

static struct PyModuleDef leveldb_extension_def = {
	PyModuleDef_HEAD_INIT,
	"leveldb",
	NULL,
	sizeof(struct leveldb_extension_state),
	leveldb_extension_methods,
	NULL,
	leveldb_extension_traverse,
	leveldb_extension_clear,
	NULL
};

#define INITERROR return NULL

extern "C" PyObject* PyInit_leveldb(void)

#else

#define INITERROR return

extern "C" void initleveldb(void)

#endif
{
#if PY_MAJOR_VERSION >= 3
	PyObject* leveldb_module = PyModule_Create(&leveldb_extension_def);
#else
	PyObject* leveldb_module = Py_InitModule3((char*)"leveldb", leveldb_extension_methods, 0);
#endif

	if (leveldb_module == 0)
		INITERROR;

	// add custom exception
	leveldb_exception = PyErr_NewException((char*)"leveldb.LevelDBError", 0, 0);

	if (leveldb_exception == 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyModule_AddObject(leveldb_module, (char*)"LevelDBError", leveldb_exception) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyLevelDB_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyLevelDBSnapshot_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	if (PyType_Ready(&PyWriteBatch_Type) < 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	// add custom types to the different modules
	Py_INCREF(&PyLevelDB_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"LevelDB", (PyObject*)&PyLevelDB_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	Py_INCREF(&PyLevelDBSnapshot_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"Snapshot", (PyObject*)&PyLevelDBSnapshot_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	Py_INCREF(&PyWriteBatch_Type);

	if (PyModule_AddObject(leveldb_module, (char*)"WriteBatch", (PyObject*)&PyWriteBatch_Type) != 0) {
		Py_DECREF(leveldb_module);
		INITERROR;
	}

	PyEval_InitThreads();

	#if PY_MAJOR_VERSION >= 3
	return leveldb_module;
	#endif
}
<|endoftext|>


<commit_before>/*
** Author(s):
**  - Herve Cuche <hcuche@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <iostream>
#include <cstring>
#include <map>
#include <stdint.h>

#include <event2/util.h>
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include "src/transport_socket_p.hpp"
#include "src/transport_socket_libevent_p.hpp"
#include "src/network_thread.hpp"
#include "src/message_p.hpp"
#include "src/buffer_p.hpp"
#include "src/session_p.hpp"

#include <qi/log.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/message.hpp>
#include <qimessaging/datastream.hpp>
#include <qimessaging/buffer.hpp>

#define MAX_LINE 16384

namespace qi
{
  static void readcb(struct bufferevent *bev,
                     void *context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->readcb(bev, context);
  }

  static void writecb(struct bufferevent* bev,
                      void* context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->writecb(bev, context);
  }

  static void eventcb(struct bufferevent *bev,
                      short error,
                      void *context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->eventcb(bev, error, context);
  }

  void TransportSocketLibEvent::readcb(struct bufferevent *bev,
                                       void               *QI_UNUSED(context))
  {
    struct evbuffer *input = bufferevent_get_input(bev);
    int              msgId = 0;
    unsigned int magicValue = qi::MessagePrivate::magic;

    while (true)
    {
      if (msg == NULL)
      {
        msg = new qi::Message();
        readHdr = true;
      }

      if (readHdr)
      {
        if (evbuffer_get_length(input) < sizeof(MessagePrivate::MessageHeader))
          return;

        struct evbuffer_ptr p;
        evbuffer_ptr_set(input, &p, 0, EVBUFFER_PTR_SET);
        // search a messageMagic number
        p = evbuffer_search(input, (const char *)&magicValue, sizeof(uint32_t), &p);
        if (p.pos < 0)
        {
          qiLogWarning("qimessaging.TransportSocketLibevent") << "No magic found in the message. Waiting for more data.";
          return;
        }
        // Drain to the magic
        evbuffer_drain(input, p.pos);
        // Get the message header
        // there is a copy here.
        evbuffer_copyout(input, msg->_p->getHeader(), sizeof(MessagePrivate::MessageHeader));
        // check if the msg is valid
        if (!msg->isValid())
        {
          qiLogError("qimessaging.TransportSocketLibevent") << "Message received is invalid! Try to find a new one.";
          // only drop the magic and restart scanning
          evbuffer_drain(input, sizeof(uint32_t));
          return;
        }
        // header is valid, next step get all the buffer
        // remove the header from the evbuffer
        evbuffer_drain(input, sizeof(MessagePrivate::MessageHeader));

        readHdr = false;
      }

      if (evbuffer_get_length(input) <
          static_cast<MessagePrivate::MessageHeader*>(msg->_p->getHeader())->size)
        return;

      /* we have to let the Buffer know we are going to push some data inside */
      qi::Buffer buf;
      buf.reserve(static_cast<MessagePrivate::MessageHeader*>(msg->_p->getHeader())->size);
      msg->setBuffer(buf);

      evbuffer_remove(input,
                      buf.data(),
                      buf.size());

      {
        boost::mutex::scoped_lock l(mtx);
        msgSend[msg->id()] = msg;
        msgId = msg->id();
        msg = NULL;
        cond.notify_all();
      }
      if (tcd)
        tcd->onSocketReadyRead(self, msgId);

    }
  }

  void TransportSocketLibEvent::writecb(struct bufferevent *QI_UNUSED(bev),
                                        void               *QI_UNUSED(context))
  {
    if (tcd)
      tcd->onSocketWriteDone(self);
  }

  void TransportSocketLibEvent::eventcb(struct bufferevent *bev,
                                        short events,
                                        void *QI_UNUSED(context))
  {
    if (events & BEV_EVENT_CONNECTED)
    {
      connected = true;
      if (tcd)
        tcd->onSocketConnected(self);
    }
    else if ((events & BEV_EVENT_EOF) || (events & BEV_EVENT_ERROR))
    {
      bufferevent_free(bev);
      bev = 0;
      bool wasco = connected;
      connected = false;
      //for waitForId
      cond.notify_all();

      if (tcd)
        tcd->onSocketConnectionError(self);
      if (wasco && tcd)
        tcd->onSocketDisconnected(self);
      status = errno;
      // check errno to see what error occurred
      qiLogVerbose("qimessaging.TransportSocketLibevent")  << "socket terminate (" << errno << "): " << strerror(errno) << std::endl;
    }
    else if (events & BEV_EVENT_TIMEOUT)
    {
      // must be a timeout event handle, handle it
      qiLogError("qimessaging.TransportSocketLibevent")  << "must be a timeout event handle, handle it" << std::endl;
    }
  }

  TransportSocketLibEvent::TransportSocketLibEvent(TransportSocket *socket)
    : TransportSocketPrivate(socket)
    , bev(NULL)
    , fd(-1)
  {
  }

  TransportSocketLibEvent::TransportSocketLibEvent(TransportSocket *socket, int fileDesc, void *data)
    : TransportSocketPrivate(socket)
    , bev(NULL)
    , fd(fileDesc)
  {
    struct event_base *base = static_cast<event_base *>(data);
    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
    bufferevent_setcb(bev, ::qi::readcb, ::qi::writecb, ::qi::eventcb, this);
    bufferevent_setwatermark(bev, EV_WRITE, 0, MAX_LINE);
    bufferevent_enable(bev, EV_READ|EV_WRITE);
    connected = true;
  }

  TransportSocketLibEvent::~TransportSocketLibEvent()
  {
    if (isConnected())
      disconnect();
  }

  void TransportSocketLibEvent::onBufferSent(const void *QI_UNUSED(data),
                                             size_t QI_UNUSED(datalen),
                                             void *buffer)
  {
    Buffer *b = static_cast<Buffer *>(buffer);
    delete b;
  }

  void TransportSocketLibEvent::onMessageSent(const void *QI_UNUSED(data),
                                              size_t QI_UNUSED(datalen),
                                              void *msg)
  {
    Message *m = static_cast<Message *>(msg);
    delete m;
  }

  bool TransportSocketLibEvent::connect(qi::Session *session,
                                        const qi::Url &url)
  {
    const std::string &address = url.host();
    struct evutil_addrinfo *ai = NULL;
    int                     err;
    struct evutil_addrinfo  hint;
    char                    portbuf[10];

    qiLogVerbose("qimessaging.transportsocket.connect") << "Trying to connect to " << url.host() << ":" << url.port();
    if (!isConnected())
    {
      bev = bufferevent_socket_new(session->_p->_networkThread->getEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
      bufferevent_setcb(bev, ::qi::readcb, ::qi::writecb, ::qi::eventcb, this);
      bufferevent_setwatermark(bev, EV_WRITE, 0, MAX_LINE);
      bufferevent_enable(bev, EV_READ|EV_WRITE);

      evutil_snprintf(portbuf, sizeof(portbuf), "%d", url.port());
      memset(&hint, 0, sizeof(hint));
      hint.ai_family = AF_UNSPEC;
      hint.ai_protocol = IPPROTO_TCP;
      hint.ai_socktype = SOCK_STREAM;
      err = evutil_getaddrinfo(address.c_str(), portbuf, &hint, &ai);
      if (err != 0)
      {
        qiLogError("qimessaging.TransportSocketLibEvent") << "Cannot resolve dns (" << address << ")";
        return (false);
      }

      int result = bufferevent_socket_connect(bev, ai->ai_addr, ai->ai_addrlen);

      if (result == 0)
        return true;

      return false;
    }
    else
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is already connected.";
    }

    return false;
  }

  void TransportSocketLibEvent::disconnect()
  {
    if (isConnected())
    {
      bufferevent_free(bev);
      bev = NULL;
      connected = false;
    }
    else
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is not connected.";
    }
  }

  bool TransportSocketLibEvent::send(const qi::Message &msg)
  {
    if (!isConnected())
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is not connected.";
      return false;
    }

    qi::Message *m = new qi::Message();
    *m = msg;
    m->_p->complete();
    assert(m->isValid());

    struct evbuffer *evb = bufferevent_get_output(bev);

    // m might be deleted.
    qi::Buffer *b = new qi::Buffer(m->buffer());

    if (evbuffer_add_reference(evb,
                               m->_p->getHeader(),
                               sizeof(qi::MessagePrivate::MessageHeader),
                               qi::TransportSocketLibEvent::onMessageSent,
                               static_cast<void *>(m)) != 0)
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "Add reference fail in header";
      delete m;
      delete b;
      return false;
    }
    size_t sz = b->size();
    if (sz) {
      if (evbuffer_add_reference(evb,
                                 b->data(),
                                 sz,
                                 qi::TransportSocketLibEvent::onBufferSent,
                                 static_cast<void *>(b)) != 0)
      {
        qiLogError("qimessaging.TransportSocketLibevent") << "Add reference fail for block of size " << sz;
        delete b;
        return false;
      }
    }
    else {
      delete b;
    }

    if (bufferevent_write_buffer(bev, evb) != 0)
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "Can't add buffer to the send queue";
      evbuffer_drain(evb, sizeof(qi::MessagePrivate::MessageHeader) + sz);
      return false;
    }

    return true;
  }
}

<commit_msg>Fix multi-threading send message though libevent<commit_after>/*
** Author(s):
**  - Herve Cuche <hcuche@aldebaran-robotics.com>
**
** Copyright (C) 2012 Aldebaran Robotics
*/

#include <iostream>
#include <cstring>
#include <map>
#include <stdint.h>

#include <event2/util.h>
#include <event2/event.h>
#include <event2/buffer.h>
#include <event2/bufferevent.h>
#include <boost/thread.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

#include "src/transport_socket_p.hpp"
#include "src/transport_socket_libevent_p.hpp"
#include "src/network_thread.hpp"
#include "src/message_p.hpp"
#include "src/buffer_p.hpp"
#include "src/session_p.hpp"

#include <qi/log.hpp>
#include <qimessaging/session.hpp>
#include <qimessaging/message.hpp>
#include <qimessaging/datastream.hpp>
#include <qimessaging/buffer.hpp>

#define MAX_LINE 16384

namespace qi
{
  static void readcb(struct bufferevent *bev,
                     void *context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->readcb(bev, context);
  }

  static void writecb(struct bufferevent* bev,
                      void* context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->writecb(bev, context);
  }

  static void eventcb(struct bufferevent *bev,
                      short error,
                      void *context)
  {
    TransportSocketLibEvent *tc = static_cast<TransportSocketLibEvent*>(context);
    tc->eventcb(bev, error, context);
  }

  void TransportSocketLibEvent::readcb(struct bufferevent *bev,
                                       void               *QI_UNUSED(context))
  {
    struct evbuffer *input = bufferevent_get_input(bev);
    int              msgId = 0;
    unsigned int magicValue = qi::MessagePrivate::magic;

    while (true)
    {
      if (msg == NULL)
      {
        msg = new qi::Message();
        readHdr = true;
      }

      if (readHdr)
      {
        if (evbuffer_get_length(input) < sizeof(MessagePrivate::MessageHeader))
          return;

        struct evbuffer_ptr p;
        evbuffer_ptr_set(input, &p, 0, EVBUFFER_PTR_SET);
        // search a messageMagic number
        p = evbuffer_search(input, (const char *)&magicValue, sizeof(uint32_t), &p);
        if (p.pos < 0)
        {
          qiLogWarning("qimessaging.TransportSocketLibevent") << "No magic found in the message. Waiting for more data.";
          return;
        }
        // Drain to the magic
        evbuffer_drain(input, p.pos);
        // Get the message header
        // there is a copy here.
        evbuffer_copyout(input, msg->_p->getHeader(), sizeof(MessagePrivate::MessageHeader));
        // check if the msg is valid
        if (!msg->isValid())
        {
          qiLogError("qimessaging.TransportSocketLibevent") << "Message received is invalid! Try to find a new one.";
          // only drop the magic and restart scanning
          evbuffer_drain(input, sizeof(uint32_t));
          return;
        }
        // header is valid, next step get all the buffer
        // remove the header from the evbuffer
        evbuffer_drain(input, sizeof(MessagePrivate::MessageHeader));

        readHdr = false;
      }

      if (evbuffer_get_length(input) <
          static_cast<MessagePrivate::MessageHeader*>(msg->_p->getHeader())->size)
        return;

      /* we have to let the Buffer know we are going to push some data inside */
      qi::Buffer buf;
      buf.reserve(static_cast<MessagePrivate::MessageHeader*>(msg->_p->getHeader())->size);
      msg->setBuffer(buf);

      evbuffer_remove(input,
                      buf.data(),
                      buf.size());

      {
        boost::mutex::scoped_lock l(mtx);
        msgSend[msg->id()] = msg;
        msgId = msg->id();
        msg = NULL;
        cond.notify_all();
      }
      if (tcd)
        tcd->onSocketReadyRead(self, msgId);

    }
  }

  void TransportSocketLibEvent::writecb(struct bufferevent *QI_UNUSED(bev),
                                        void               *QI_UNUSED(context))
  {
    if (tcd)
      tcd->onSocketWriteDone(self);
  }

  void TransportSocketLibEvent::eventcb(struct bufferevent *bev,
                                        short events,
                                        void *QI_UNUSED(context))
  {
    if (events & BEV_EVENT_CONNECTED)
    {
      connected = true;
      if (tcd)
        tcd->onSocketConnected(self);
    }
    else if ((events & BEV_EVENT_EOF) || (events & BEV_EVENT_ERROR))
    {
      bufferevent_free(bev);
      bev = 0;
      bool wasco = connected;
      connected = false;
      //for waitForId
      cond.notify_all();

      if (tcd)
        tcd->onSocketConnectionError(self);
      if (wasco && tcd)
        tcd->onSocketDisconnected(self);
      status = errno;
      // check errno to see what error occurred
      qiLogVerbose("qimessaging.TransportSocketLibevent")  << "socket terminate (" << errno << "): " << strerror(errno) << std::endl;
    }
    else if (events & BEV_EVENT_TIMEOUT)
    {
      // must be a timeout event handle, handle it
      qiLogError("qimessaging.TransportSocketLibevent")  << "must be a timeout event handle, handle it" << std::endl;
    }
  }

  TransportSocketLibEvent::TransportSocketLibEvent(TransportSocket *socket)
    : TransportSocketPrivate(socket)
    , bev(NULL)
    , fd(-1)
  {
  }

  TransportSocketLibEvent::TransportSocketLibEvent(TransportSocket *socket, int fileDesc, void *data)
    : TransportSocketPrivate(socket)
    , bev(NULL)
    , fd(fileDesc)
  {
    struct event_base *base = static_cast<event_base *>(data);
    bev = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
    bufferevent_setcb(bev, ::qi::readcb, ::qi::writecb, ::qi::eventcb, this);
    bufferevent_setwatermark(bev, EV_WRITE, 0, MAX_LINE);
    bufferevent_enable(bev, EV_READ|EV_WRITE);
    connected = true;
  }

  TransportSocketLibEvent::~TransportSocketLibEvent()
  {
    if (isConnected())
      disconnect();
  }

  void TransportSocketLibEvent::onBufferSent(const void *QI_UNUSED(data),
                                             size_t QI_UNUSED(datalen),
                                             void *buffer)
  {
    Buffer *b = static_cast<Buffer *>(buffer);
    delete b;
  }

  void TransportSocketLibEvent::onMessageSent(const void *QI_UNUSED(data),
                                              size_t QI_UNUSED(datalen),
                                              void *msg)
  {
    Message *m = static_cast<Message *>(msg);
    delete m;
  }

  bool TransportSocketLibEvent::connect(qi::Session *session,
                                        const qi::Url &url)
  {
    const std::string &address = url.host();
    struct evutil_addrinfo *ai = NULL;
    int                     err;
    struct evutil_addrinfo  hint;
    char                    portbuf[10];

    qiLogVerbose("qimessaging.transportsocket.connect") << "Trying to connect to " << url.host() << ":" << url.port();
    if (!isConnected())
    {
      bev = bufferevent_socket_new(session->_p->_networkThread->getEventBase(), -1, BEV_OPT_CLOSE_ON_FREE | BEV_OPT_THREADSAFE);
      bufferevent_setcb(bev, ::qi::readcb, ::qi::writecb, ::qi::eventcb, this);
      bufferevent_setwatermark(bev, EV_WRITE, 0, MAX_LINE);
      bufferevent_enable(bev, EV_READ|EV_WRITE);

      evutil_snprintf(portbuf, sizeof(portbuf), "%d", url.port());
      memset(&hint, 0, sizeof(hint));
      hint.ai_family = AF_UNSPEC;
      hint.ai_protocol = IPPROTO_TCP;
      hint.ai_socktype = SOCK_STREAM;
      err = evutil_getaddrinfo(address.c_str(), portbuf, &hint, &ai);
      if (err != 0)
      {
        qiLogError("qimessaging.TransportSocketLibEvent") << "Cannot resolve dns (" << address << ")";
        return (false);
      }

      int result = bufferevent_socket_connect(bev, ai->ai_addr, ai->ai_addrlen);

      if (result == 0)
        return true;

      return false;
    }
    else
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is already connected.";
    }

    return false;
  }

  void TransportSocketLibEvent::disconnect()
  {
    if (isConnected())
    {
      bufferevent_free(bev);
      bev = NULL;
      connected = false;
    }
    else
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is not connected.";
    }
  }

  bool TransportSocketLibEvent::send(const qi::Message &msg)
  {
    if (!isConnected())
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "socket is not connected.";
      return false;
    }

    qi::Message *m = new qi::Message();
    *m = msg;
    m->_p->complete();

    struct evbuffer *mess = evbuffer_new();
    // m might be deleted.
    qi::Buffer *b = new qi::Buffer(m->buffer());
    if (evbuffer_add_reference(mess,
                               m->_p->getHeader(),
                               sizeof(qi::MessagePrivate::MessageHeader),
                               qi::TransportSocketLibEvent::onMessageSent,
                               static_cast<void *>(m)) != 0)
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "Add reference fail in header";
      evbuffer_free(mess);
      delete m;
      delete b;
      return false;
    }
    size_t sz = b->size();

    if (sz)
    {
      if (evbuffer_add_reference(mess,
                                 b->data(),
                                 sz,
                                 qi::TransportSocketLibEvent::onBufferSent,
                                 static_cast<void *>(b)) != 0)
      {
        qiLogError("qimessaging.TransportSocketLibevent") << "Add reference fail for block of size " << sz;
        evbuffer_free(mess);
        delete b;
        return false;
      }
    }
    else
    {
      delete b;
    }

    if (bufferevent_write_buffer(bev, mess) != 0)
    {
      qiLogError("qimessaging.TransportSocketLibevent") << "Can't add buffer to the send queue";
      evbuffer_free(mess);
      return false;
    }
    evbuffer_free(mess);
    return true;
  }
}

<|endoftext|>


<commit_before>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/onboard/fusion_subnode.h"

#include <unordered_map>

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/log.h"
#include "modules/perception/common/perception_gflags.h"
#include "modules/perception/onboard/event_manager.h"
#include "modules/perception/onboard/shared_data_manager.h"
#include "modules/perception/onboard/subnode_helper.h"

namespace apollo {
namespace perception {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;

bool FusionSubnode::InitInternal() {
  RegistAllAlgorithm();

  AdapterManager::Init(FLAGS_perception_adapter_config_filename);

  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";
  AdapterManager::AddChassisCallback(&FusionSubnode::OnChassis, this);

  CHECK(shared_data_manager_ != nullptr);
  fusion_.reset(BaseFusionRegisterer::GetInstanceByName(FLAGS_onboard_fusion));
  if (fusion_ == nullptr) {
    AERROR << "Failed to get fusion instance: " << FLAGS_onboard_fusion;
    return false;
  }
  if (!fusion_->Init()) {
    AERROR << "Failed to init fusion:" << FLAGS_onboard_fusion;
    return false;
  }
  radar_object_data_ = dynamic_cast<RadarObjectData *>(
      shared_data_manager_->GetSharedData("RadarObjectData"));
  if (radar_object_data_ == nullptr) {
    AWARN << "Failed to get RadarObjectData.";
  }
  lidar_object_data_ = dynamic_cast<LidarObjectData *>(
      shared_data_manager_->GetSharedData("LidarObjectData"));
  if (lidar_object_data_ == nullptr) {
    AWARN << "Failed to get LidarObjectData.";
  }
  camera_object_data_ = dynamic_cast<CameraObjectData *>(
      shared_data_manager_->GetSharedData("CameraObjectData"));
  if (camera_object_data_ == nullptr) {
    AWARN << "Failed to get CameraObjectData.";
  }

  fusion_data_ = dynamic_cast<FusionSharedData *>(
      shared_data_manager_->GetSharedData("FusionSharedData"));
  if (fusion_data_ == nullptr) {
    AWARN << "Failed to get FusionSharedData.";
  }

  lane_shared_data_ = dynamic_cast<LaneSharedData *>(
      shared_data_manager_->GetSharedData("LaneSharedData"));
  if (lane_shared_data_ == nullptr) {
    AWARN << "failed to get shared data instance: LaneSharedData ";
  }

  lane_objects_.reset(new LaneObjects());

  if (!InitOutputStream()) {
    AERROR << "Failed to init output stream.";
    return false;
  }

  AINFO << "Init FusionSubnode succ. Using fusion:" << fusion_->name();
  return true;
}

bool FusionSubnode::InitOutputStream() {
  // expect reserve_ format:
  //       pub_driven_event_id:n
  //       lidar_output_stream : event_id=n&sink_type=m&sink_name=x
  //       radar_output_stream : event_id=n&sink_type=m&sink_name=x
  std::unordered_map<std::string, std::string> reserve_field_map;
  if (!SubnodeHelper::ParseReserveField(reserve_, &reserve_field_map)) {
    AERROR << "Failed to parse reserve string: " << reserve_;
    return false;
  }
  auto iter = reserve_field_map.find("pub_driven_event_id");
  if (iter == reserve_field_map.end()) {
    AERROR << "Failed to find pub_driven_event_id:" << reserve_;
    return false;
  }
  pub_driven_event_id_ = static_cast<EventID>(atoi((iter->second).c_str()));

  auto lidar_iter = reserve_field_map.find("lidar_event_id");
  if (lidar_iter == reserve_field_map.end()) {
    AWARN << "Failed to find lidar_event_id:" << reserve_;
    AINFO << "lidar_event_id will be set -1";
    lidar_event_id_ = -1;
  } else {
    lidar_event_id_ = static_cast<EventID>(atoi((lidar_iter->second).c_str()));
  }

  auto radar_iter = reserve_field_map.find("radar_event_id");
  if (radar_iter == reserve_field_map.end()) {
    AWARN << "Failed to find radar_event_id:" << reserve_;
    AINFO << "radar_event_id will be set -1";
    radar_event_id_ = -1;
  } else {
    radar_event_id_ = static_cast<EventID>(atoi((radar_iter->second).c_str()));
  }

  auto camera_iter = reserve_field_map.find("camera_event_id");
  if (camera_iter == reserve_field_map.end()) {
    AWARN << "Failed to find camera_event_id:" << reserve_;
    AINFO << "camera_event_id will be set -1";
    camera_event_id_ = -1;
  } else {
    camera_event_id_ =
        static_cast<EventID>(atoi((camera_iter->second).c_str()));
  }

  auto lane_iter = reserve_field_map.find("lane_event_id");
  if (lane_iter == reserve_field_map.end()) {
    AWARN << "Failed to find camera_event_id:" << reserve_;
    AINFO << "camera_event_id will be set -1";
    lane_event_id_ = -1;
  } else {
    lane_event_id_ = static_cast<EventID>(atoi((lane_iter->second).c_str()));
  }

  return true;
}

Status FusionSubnode::ProcEvents() {
  for (auto event_meta : sub_meta_events_) {
    // ignore lane event from polling
    if (event_meta.event_id == lane_event_id_) continue;

    std::vector<Event> events;
    if (!SubscribeEvents(event_meta, &events)) {
      AERROR << "event meta id:" << event_meta.event_id << " "
             << event_meta.from_node << " " << event_meta.to_node;
      return Status(ErrorCode::PERCEPTION_ERROR, "Subscribe event fail.");
    }
    if (events.empty()) {
      usleep(500);
      continue;
    }
    Process(event_meta, events);

    if (event_meta.event_id != pub_driven_event_id_) {
      ADEBUG << "Not pub_driven_event_id, skip to publish."
             << " event_id:" << event_meta.event_id
             << " fused_obj_cnt:" << objects_.size();
      continue;
    }

    // public obstacle message
    PerceptionObstacles obstacles;
    if (GeneratePbMsg(&obstacles)) {
      common::adapter::AdapterManager::PublishPerceptionObstacles(obstacles);
    }
    AINFO << "Publish 3d perception fused msg. timestamp:"
          << GLOG_TIMESTAMP(timestamp_) << " obj_cnt:" << objects_.size();
  }
  return Status::OK();
}

Status FusionSubnode::Process(const EventMeta &event_meta,
                              const std::vector<Event> &events) {
  std::vector<SensorObjects> sensor_objs;
  if (!BuildSensorObjs(events, &sensor_objs)) {
    AERROR << "Failed to build_sensor_objs";
    error_code_ = common::PERCEPTION_ERROR_PROCESS;
    return Status(ErrorCode::PERCEPTION_ERROR, "Failed to build_sensor_objs.");
  }
  PERF_BLOCK_START();
  objects_.clear();
  if (!fusion_->Fuse(sensor_objs, &objects_)) {
    AWARN << "Failed to call fusion plugin."
          << " event_meta: [" << event_meta.to_string()
          << "] event_cnt:" << events.size() << " event_0: ["
          << events[0].to_string() << "]";
    error_code_ = common::PERCEPTION_ERROR_PROCESS;
    return Status(ErrorCode::PERCEPTION_ERROR, "Failed to call fusion plugin.");
  }
  if (event_meta.event_id == lidar_event_id_) {
    PERF_BLOCK_END("fusion_lidar");
  } else if (event_meta.event_id == radar_event_id_) {
    PERF_BLOCK_END("fusion_radar");
  } else if (event_meta.event_id == camera_event_id_) {
    PERF_BLOCK_END("fusion_camera");
  }

  if (objects_.size() > 0 && FLAGS_publish_fusion_event) {
    SharedDataPtr<FusionItem> fusion_item_ptr(new FusionItem);
    fusion_item_ptr->timestamp = objects_[0]->latest_tracked_time;
    const std::string &device_id = events[0].reserve;
    for (auto obj : objects_) {
      ObjectPtr objclone(new Object());
      objclone->clone(*obj);
      fusion_item_ptr->obstacles.push_back(objclone);
    }
    AINFO << "publishing event for timestamp deviceid and size of fusion object"
          << fusion_item_ptr->timestamp << " " << device_id << " "
          << fusion_item_ptr->obstacles.size();
    PublishDataAndEvent(fusion_item_ptr->timestamp, device_id, fusion_item_ptr);
  }

  timestamp_ = sensor_objs[0].timestamp;
  error_code_ = common::OK;
  return Status::OK();
}

void FusionSubnode::PublishDataAndEvent(const double &timestamp,
                                        const std::string &device_id,
                                        const SharedDataPtr<FusionItem> &data) {
  CommonSharedDataKey key(timestamp, device_id);
  bool fusion_succ = fusion_data_->Add(key, data);
  if (!fusion_succ) {
    AERROR << "fusion shared data addkey failure";
  }
  AINFO << "adding key in fusion shared data " << key.ToString();

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta &event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id;
    event_manager_->Publish(event);
  }
}

bool FusionSubnode::SubscribeEvents(const EventMeta &event_meta,
                                    std::vector<Event> *events) const {
  Event event;
  // no blocking
  while (event_manager_->Subscribe(event_meta.event_id, &event, true)) {
    events->push_back(event);
  }
  return true;
}
bool FusionSubnode::BuildSensorObjs(
    const std::vector<Event> &events,
    std::vector<SensorObjects> *multi_sensor_objs) {
  PERF_FUNCTION();
  for (auto event : events) {
    std::shared_ptr<SensorObjects> sensor_objects;
    if (!GetSharedData(event, &sensor_objects)) {
      return false;
    }
    // Make sure timestamp and type are filled.
    sensor_objects->timestamp = event.timestamp;
    if (event.event_id == lidar_event_id_) {
      sensor_objects->sensor_type = SensorType::VELODYNE_64;
    } else if (event.event_id == radar_event_id_) {
      sensor_objects->sensor_type = SensorType::RADAR;
    } else if (event.event_id == camera_event_id_) {
      sensor_objects->sensor_type = SensorType::CAMERA;
    } else {
      AERROR << "Event id is not supported. event:" << event.to_string();
      return false;
    }
    sensor_objects->sensor_id = GetSensorType(sensor_objects->sensor_type);
    multi_sensor_objs->push_back(*sensor_objects);
    ADEBUG << "get sensor objs:" << sensor_objects->ToString();
  }
  return true;
}

bool FusionSubnode::GetSharedData(const Event &event,
                                  std::shared_ptr<SensorObjects> *objs) {
  double timestamp = event.timestamp;
  const std::string &device_id = event.reserve;
  std::string data_key;
  if (!SubnodeHelper::ProduceSharedDataKey(timestamp, device_id, &data_key)) {
    AERROR << "Failed to produce shared data key. EventID:" << event.event_id
           << " timestamp:" << timestamp << " device_id:" << device_id;
    return false;
  }
  bool get_data_succ = false;
  if (event.event_id == lidar_event_id_ && lidar_object_data_ != nullptr) {
    get_data_succ = lidar_object_data_->Get(data_key, objs);
  } else if (event.event_id == radar_event_id_ &&
             radar_object_data_ != nullptr) {
    get_data_succ = radar_object_data_->Get(data_key, objs);
  } else if (event.event_id == camera_event_id_ &&
             camera_object_data_ != nullptr) {
    get_data_succ = camera_object_data_->Get(data_key, objs);
    // trying to get lane shared data as well
    Event lane_event;
    if (event_manager_->Subscribe(lane_event_id_, &lane_event, false)) {
      get_data_succ = lane_shared_data_->Get(data_key, &lane_objects_);
      ADEBUG << "getting lane data successfully for data key " << data_key;
    }
  } else {
    AERROR << "Event id is not supported. event:" << event.to_string();
    return false;
  }
  if (!get_data_succ) {
    AERROR << "Failed to get shared data. event:" << event.to_string();
    return false;
  }
  return true;
}

bool FusionSubnode::GeneratePbMsg(PerceptionObstacles *obstacles) {
  common::adapter::AdapterManager::FillPerceptionObstaclesHeader(
      FLAGS_obstacle_module_name, obstacles);
  common::Header *header = obstacles->mutable_header();
  if (pub_driven_event_id_ == lidar_event_id_) {
    header->set_lidar_timestamp(timestamp_ * 1e9);  // in ns
    header->set_camera_timestamp(0);
    header->set_radar_timestamp(0);
  } else if (pub_driven_event_id_ == camera_event_id_) {
    header->set_lidar_timestamp(0);  // in ns
    header->set_camera_timestamp(timestamp_ * 1e9);
    header->set_radar_timestamp(0);
  }

  obstacles->set_error_code(error_code_);

  for (const auto &obj : objects_) {
    PerceptionObstacle *obstacle = obstacles->add_perception_obstacle();
    obj->Serialize(obstacle);
  }

  if (FLAGS_use_navigation_mode) {
    // generate lane marker protobuf messages
    LaneMarkers *lane_markers = obstacles->mutable_lane_marker();
    LaneObjectsToLaneMarkerProto(*(lane_objects_), lane_markers);

    // Relative speed of objects + latest ego car speed in X
    for (auto obstacle : obstacles->perception_obstacle()) {
      obstacle.mutable_velocity()->set_x(obstacle.velocity().x() +
                                         chassis_speed_mps_);
    }
  }

  ADEBUG << "PerceptionObstacles: " << obstacles->ShortDebugString();
  return true;
}

void FusionSubnode::RegistAllAlgorithm() {
  RegisterFactoryProbabilisticFusion();
  RegisterFactoryAsyncFusion();
}

void FusionSubnode::OnChassis(const Chassis &chassis) {
  ADEBUG << "Received chassis data: run chassis callback.";
  chassis_.CopyFrom(chassis);
  chassis_speed_mps_ = chassis_.speed_mps();
}

}  // namespace perception
}  // namespace apollo
<commit_msg>Perception: Fix a bug in fusion about not initialized<commit_after>/******************************************************************************
 * Copyright 2017 The Apollo Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *****************************************************************************/

#include "modules/perception/obstacle/onboard/fusion_subnode.h"

#include <unordered_map>

#include "modules/common/adapters/adapter_manager.h"
#include "modules/common/configs/config_gflags.h"
#include "modules/common/log.h"
#include "modules/perception/common/perception_gflags.h"
#include "modules/perception/onboard/event_manager.h"
#include "modules/perception/onboard/shared_data_manager.h"
#include "modules/perception/onboard/subnode_helper.h"

namespace apollo {
namespace perception {

using apollo::canbus::Chassis;
using apollo::common::ErrorCode;
using apollo::common::Status;
using apollo::common::adapter::AdapterManager;

bool FusionSubnode::InitInternal() {
  RegistAllAlgorithm();

  AdapterManager::Init(FLAGS_perception_adapter_config_filename);

  CHECK(AdapterManager::GetChassis()) << "Chassis is not initialized.";
  AdapterManager::AddChassisCallback(&FusionSubnode::OnChassis, this);

  CHECK(shared_data_manager_ != nullptr);
  fusion_.reset(BaseFusionRegisterer::GetInstanceByName(FLAGS_onboard_fusion));
  if (fusion_ == nullptr) {
    AERROR << "Failed to get fusion instance: " << FLAGS_onboard_fusion;
    return false;
  }
  if (!fusion_->Init()) {
    AERROR << "Failed to init fusion:" << FLAGS_onboard_fusion;
    return false;
  }
  radar_object_data_ = dynamic_cast<RadarObjectData *>(
      shared_data_manager_->GetSharedData("RadarObjectData"));
  if (radar_object_data_ == nullptr) {
    AWARN << "Failed to get RadarObjectData.";
  }
  lidar_object_data_ = dynamic_cast<LidarObjectData *>(
      shared_data_manager_->GetSharedData("LidarObjectData"));
  if (lidar_object_data_ == nullptr) {
    AWARN << "Failed to get LidarObjectData.";
  }
  camera_object_data_ = dynamic_cast<CameraObjectData *>(
      shared_data_manager_->GetSharedData("CameraObjectData"));
  if (camera_object_data_ == nullptr) {
    AWARN << "Failed to get CameraObjectData.";
  }

  fusion_data_ = dynamic_cast<FusionSharedData *>(
      shared_data_manager_->GetSharedData("FusionSharedData"));
  if (fusion_data_ == nullptr) {
    AWARN << "Failed to get FusionSharedData.";
  }

  lane_shared_data_ = dynamic_cast<LaneSharedData *>(
      shared_data_manager_->GetSharedData("LaneSharedData"));
  if (lane_shared_data_ == nullptr) {
    AWARN << "failed to get shared data instance: LaneSharedData ";
  }

  lane_objects_.reset(new LaneObjects());

  if (!InitOutputStream()) {
    AERROR << "Failed to init output stream.";
    return false;
  }

  AINFO << "Init FusionSubnode succ. Using fusion:" << fusion_->name();
  return true;
}

bool FusionSubnode::InitOutputStream() {
  // expect reserve_ format:
  //       pub_driven_event_id:n
  //       lidar_output_stream : event_id=n&sink_type=m&sink_name=x
  //       radar_output_stream : event_id=n&sink_type=m&sink_name=x
  std::unordered_map<std::string, std::string> reserve_field_map;
  if (!SubnodeHelper::ParseReserveField(reserve_, &reserve_field_map)) {
    AERROR << "Failed to parse reserve string: " << reserve_;
    return false;
  }
  auto iter = reserve_field_map.find("pub_driven_event_id");
  if (iter == reserve_field_map.end()) {
    AERROR << "Failed to find pub_driven_event_id:" << reserve_;
    return false;
  }
  pub_driven_event_id_ = static_cast<EventID>(atoi((iter->second).c_str()));

  auto lidar_iter = reserve_field_map.find("lidar_event_id");
  if (lidar_iter == reserve_field_map.end()) {
    AWARN << "Failed to find lidar_event_id:" << reserve_;
    AINFO << "lidar_event_id will be set -1";
    lidar_event_id_ = -1;
  } else {
    lidar_event_id_ = static_cast<EventID>(atoi((lidar_iter->second).c_str()));
  }

  auto radar_iter = reserve_field_map.find("radar_event_id");
  if (radar_iter == reserve_field_map.end()) {
    AWARN << "Failed to find radar_event_id:" << reserve_;
    AINFO << "radar_event_id will be set -1";
    radar_event_id_ = -1;
  } else {
    radar_event_id_ = static_cast<EventID>(atoi((radar_iter->second).c_str()));
  }

  auto camera_iter = reserve_field_map.find("camera_event_id");
  if (camera_iter == reserve_field_map.end()) {
    AWARN << "Failed to find camera_event_id:" << reserve_;
    AINFO << "camera_event_id will be set -1";
    camera_event_id_ = -1;
  } else {
    camera_event_id_ =
        static_cast<EventID>(atoi((camera_iter->second).c_str()));
  }

  auto lane_iter = reserve_field_map.find("lane_event_id");
  if (lane_iter == reserve_field_map.end()) {
    AWARN << "Failed to find lane_event_id_:" << reserve_;
    AINFO << "lane_event_id_ will be set -1";
    lane_event_id_ = -1;
  } else {
    lane_event_id_ = static_cast<EventID>(atoi((lane_iter->second).c_str()));
  }

  return true;
}

Status FusionSubnode::ProcEvents() {
  for (auto event_meta : sub_meta_events_) {
    if (event_meta.event_id == lane_event_id_) continue;  // ignore lane event

    std::vector<Event> events;
    if (!SubscribeEvents(event_meta, &events)) {
      AERROR << "event meta id:" << event_meta.event_id << " "
             << event_meta.from_node << " " << event_meta.to_node;
      return Status(ErrorCode::PERCEPTION_ERROR, "Subscribe event fail.");
    }
    if (events.empty()) {
      usleep(500);
      continue;
    }
    Process(event_meta, events);

    if (event_meta.event_id != pub_driven_event_id_) {
      ADEBUG << "Not pub_driven_event_id, skip to publish."
             << " event_id:" << event_meta.event_id
             << " fused_obj_cnt:" << objects_.size();
      continue;
    }

    // public obstacle message
    PerceptionObstacles obstacles;
    if (GeneratePbMsg(&obstacles)) {
      common::adapter::AdapterManager::PublishPerceptionObstacles(obstacles);
    }
    AINFO << "Publish 3d perception fused msg. timestamp:"
          << GLOG_TIMESTAMP(timestamp_) << " obj_cnt:" << objects_.size();
  }
  return Status::OK();
}

Status FusionSubnode::Process(const EventMeta &event_meta,
                              const std::vector<Event> &events) {
  std::vector<SensorObjects> sensor_objs;
  if (!BuildSensorObjs(events, &sensor_objs)) {
    AERROR << "Failed to build_sensor_objs";
    error_code_ = common::PERCEPTION_ERROR_PROCESS;
    return Status(ErrorCode::PERCEPTION_ERROR, "Failed to build_sensor_objs.");
  }
  PERF_BLOCK_START();
  objects_.clear();
  if (!fusion_->Fuse(sensor_objs, &objects_)) {
    AWARN << "Failed to call fusion plugin."
          << " event_meta: [" << event_meta.to_string()
          << "] event_cnt:" << events.size() << " event_0: ["
          << events[0].to_string() << "]";
    error_code_ = common::PERCEPTION_ERROR_PROCESS;
    return Status(ErrorCode::PERCEPTION_ERROR, "Failed to call fusion plugin.");
  }
  if (event_meta.event_id == lidar_event_id_) {
    PERF_BLOCK_END("fusion_lidar");
  } else if (event_meta.event_id == radar_event_id_) {
    PERF_BLOCK_END("fusion_radar");
  } else if (event_meta.event_id == camera_event_id_) {
    PERF_BLOCK_END("fusion_camera");
  }

  if (objects_.size() > 0 && FLAGS_publish_fusion_event) {
    SharedDataPtr<FusionItem> fusion_item_ptr(new FusionItem);
    fusion_item_ptr->timestamp = objects_[0]->latest_tracked_time;
    const std::string &device_id = events[0].reserve;
    for (auto obj : objects_) {
      ObjectPtr objclone(new Object());
      objclone->clone(*obj);
      fusion_item_ptr->obstacles.push_back(objclone);
    }
    AINFO << "publishing event for timestamp deviceid and size of fusion object"
          << fusion_item_ptr->timestamp << " " << device_id << " "
          << fusion_item_ptr->obstacles.size();
    PublishDataAndEvent(fusion_item_ptr->timestamp, device_id, fusion_item_ptr);
  }

  timestamp_ = sensor_objs[0].timestamp;
  error_code_ = common::OK;
  return Status::OK();
}

void FusionSubnode::PublishDataAndEvent(const double &timestamp,
                                        const std::string &device_id,
                                        const SharedDataPtr<FusionItem> &data) {
  CommonSharedDataKey key(timestamp, device_id);
  bool fusion_succ = fusion_data_->Add(key, data);
  if (!fusion_succ) {
    AERROR << "fusion shared data addkey failure";
  }
  AINFO << "adding key in fusion shared data " << key.ToString();

  for (size_t idx = 0; idx < pub_meta_events_.size(); ++idx) {
    const EventMeta &event_meta = pub_meta_events_[idx];
    Event event;
    event.event_id = event_meta.event_id;
    event.timestamp = timestamp;
    event.reserve = device_id;
    event_manager_->Publish(event);
  }
}

bool FusionSubnode::SubscribeEvents(const EventMeta &event_meta,
                                    std::vector<Event> *events) const {
  Event event;
  // no blocking
  while (event_manager_->Subscribe(event_meta.event_id, &event, true)) {
    events->push_back(event);
  }
  return true;
}
bool FusionSubnode::BuildSensorObjs(
    const std::vector<Event> &events,
    std::vector<SensorObjects> *multi_sensor_objs) {
  PERF_FUNCTION();
  for (auto event : events) {
    std::shared_ptr<SensorObjects> sensor_objects;
    if (!GetSharedData(event, &sensor_objects)) {
      return false;
    }
    // Make sure timestamp and type are filled.
    sensor_objects->timestamp = event.timestamp;
    if (event.event_id == lidar_event_id_) {
      sensor_objects->sensor_type = SensorType::VELODYNE_64;
    } else if (event.event_id == radar_event_id_) {
      sensor_objects->sensor_type = SensorType::RADAR;
    } else if (event.event_id == camera_event_id_) {
      sensor_objects->sensor_type = SensorType::CAMERA;
    } else {
      AERROR << "Event id is not supported. event:" << event.to_string();
      return false;
    }
    sensor_objects->sensor_id = GetSensorType(sensor_objects->sensor_type);
    multi_sensor_objs->push_back(*sensor_objects);
    ADEBUG << "get sensor objs:" << sensor_objects->ToString();
  }
  return true;
}

bool FusionSubnode::GetSharedData(const Event &event,
                                  std::shared_ptr<SensorObjects> *objs) {
  double timestamp = event.timestamp;
  const std::string &device_id = event.reserve;
  std::string data_key;
  if (!SubnodeHelper::ProduceSharedDataKey(timestamp, device_id, &data_key)) {
    AERROR << "Failed to produce shared data key. EventID:" << event.event_id
           << " timestamp:" << timestamp << " device_id:" << device_id;
    return false;
  }
  bool get_data_succ = false;
  if (event.event_id == lidar_event_id_ && lidar_object_data_ != nullptr) {
    get_data_succ = lidar_object_data_->Get(data_key, objs);
  } else if (event.event_id == radar_event_id_ &&
             radar_object_data_ != nullptr) {
    get_data_succ = radar_object_data_->Get(data_key, objs);
  } else if (event.event_id == camera_event_id_ &&
             camera_object_data_ != nullptr) {
    get_data_succ = camera_object_data_->Get(data_key, objs);

    if (lane_shared_data_ != nullptr && lane_event_id_ != -1) {
      Event lane_event;
      if (event_manager_->Subscribe(lane_event_id_, &lane_event, false)) {
        get_data_succ = lane_shared_data_->Get(data_key, &lane_objects_);
        ADEBUG << "getting lane data successfully for data key " << data_key;
      }
    }
  } else {
    AERROR << "Event id is not supported. event:" << event.to_string();
    return false;
  }
  if (!get_data_succ) {
    AERROR << "Failed to get shared data. event:" << event.to_string();
    return false;
  }
  return true;
}

bool FusionSubnode::GeneratePbMsg(PerceptionObstacles *obstacles) {
  common::adapter::AdapterManager::FillPerceptionObstaclesHeader(
      FLAGS_obstacle_module_name, obstacles);
  common::Header *header = obstacles->mutable_header();
  if (pub_driven_event_id_ == lidar_event_id_) {
    header->set_lidar_timestamp(timestamp_ * 1e9);  // in ns
    header->set_camera_timestamp(0);
    header->set_radar_timestamp(0);
  } else if (pub_driven_event_id_ == camera_event_id_) {
    header->set_lidar_timestamp(0);  // in ns
    header->set_camera_timestamp(timestamp_ * 1e9);
    header->set_radar_timestamp(0);
  }

  obstacles->set_error_code(error_code_);

  for (const auto &obj : objects_) {
    PerceptionObstacle *obstacle = obstacles->add_perception_obstacle();
    obj->Serialize(obstacle);
  }

  if (FLAGS_use_navigation_mode) {
    // Relative speed of objects + latest ego car speed in X
    for (auto obstacle : obstacles->perception_obstacle()) {
      obstacle.mutable_velocity()->set_x(obstacle.velocity().x() +
                                         chassis_speed_mps_);
    }

    // generate lane marker protobuf messages
    if (lane_shared_data_ != nullptr && lane_event_id_ != -1) {
      LaneMarkers *lane_markers = obstacles->mutable_lane_marker();
      LaneObjectsToLaneMarkerProto(*(lane_objects_), lane_markers);
    }
  }

  ADEBUG << "PerceptionObstacles: " << obstacles->ShortDebugString();
  return true;
}

void FusionSubnode::RegistAllAlgorithm() {
  RegisterFactoryProbabilisticFusion();
  RegisterFactoryAsyncFusion();
}

void FusionSubnode::OnChassis(const Chassis &chassis) {
  ADEBUG << "Received chassis data: run chassis callback.";
  chassis_.CopyFrom(chassis);
  chassis_speed_mps_ = chassis_.speed_mps();
}

}  // namespace perception
}  // namespace apollo
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: manip.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: obo $ $Date: 2004-11-15 13:38:02 $
 *
 *  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 ARY_MANIP_HXX
#define ARY_MANIP_HXX

template <class XY >
class Manipulator
{
  public:
    virtual             ~Manipulator() {}

    void                operator()(
                            XY &                io_r ) const
                            { op_fcall(io_r); }
  private:
    virtual void        op_fcall(
                            XY &                io_r ) const = 0;
};

template <class XY >
class Const_Manipulator
{
  public:
    virtual             ~Const_Manipulator() {}

    void                operator()(
                            const XY &          io_r ) const
                            { op_fcall(io_r); }
  private:
    virtual void        op_fcall(
                            const XY &          io_r ) const = 0;
};

#endif

<commit_msg>INTEGRATION: CWS ooo19126 (1.2.18); FILE MERGED 2005/09/05 13:11:31 rt 1.2.18.1: #i54170# Change license header: remove SISSL<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: manip.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: rt $ $Date: 2005-09-07 18:09:37 $
 *
 *  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 ARY_MANIP_HXX
#define ARY_MANIP_HXX

template <class XY >
class Manipulator
{
  public:
    virtual             ~Manipulator() {}

    void                operator()(
                            XY &                io_r ) const
                            { op_fcall(io_r); }
  private:
    virtual void        op_fcall(
                            XY &                io_r ) const = 0;
};

template <class XY >
class Const_Manipulator
{
  public:
    virtual             ~Const_Manipulator() {}

    void                operator()(
                            const XY &          io_r ) const
                            { op_fcall(io_r); }
  private:
    virtual void        op_fcall(
                            const XY &          io_r ) const = 0;
};

#endif

<|endoftext|>