<commit_before>// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "registryhelpers.h"
#include "dxsubfilter_uuids.h"
#include "dxsubfilter.h"

//------------------------------------------------------------------------------
// Global filter information for proper DirectShow registration

AMOVIESETUP_MEDIATYPE sudVideoMediaTypes[] = {
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_AYUV },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_YUY2 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_YV12 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_NV12 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P210 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P216 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P010 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P016 },
};

AMOVIESETUP_MEDIATYPE sudSubtitleMediaTypes[] = {
	{ &MEDIATYPE_Text, &MEDIASUBTYPE_None },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_UTF8 },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_SSA },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_ASS },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_VOBSUB },
};

AMOVIESETUP_PIN sudOutputPin = {
    L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    TRUE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudVideoMediaTypes),      // Number of media types.
    sudVideoMediaTypes					// Pointer to media types.
};

AMOVIESETUP_PIN sudInputVideoPin = {
	L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    FALSE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudVideoMediaTypes),      // Number of media types.
    sudVideoMediaTypes					// Pointer to media types.
};

AMOVIESETUP_PIN sudInputSubtitlePin = {
	L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    FALSE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudSubtitleMediaTypes),   // Number of media types.
    sudSubtitleMediaTypes				// Pointer to media types.
};

AMOVIESETUP_PIN sudDXSubFilterPins[] = {
	sudInputVideoPin,
	sudInputSubtitlePin,
	sudOutputPin,
};

AMOVIESETUP_FILTER sudDXSubFilterReg = {
    &CLSID_DXSubFilter,				// Filter CLSID.
	L"DXSubFilter",					// Filter name.
    MERIT_NORMAL,					// Merit.
	ARRAYSIZE(sudDXSubFilterPins),	// Number of pin types.
    sudDXSubFilterPins				// Pointer to pin information.
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/* List of class IDs and creator functions for the class factory. This
   provides the link between the OLE entry point in the DLL and an object
   being created. The class factory will call the static CreateInstance
   function when it is asked to create a CLSID_DXSubFilter object */

CFactoryTemplate g_Templates[1] = {
    {
		L"CDXSubFilter",							// Name
		&CLSID_DXSubFilter,							// CLSID
		DXSubFilter::CDXSubFilter::CreateInstance,	// Creation function
		NULL,										// Initialization function (optional)
		&sudDXSubFilterReg							// Pointer to filter information
	}
};

int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
//	DLL Entry Point	for normal DLLs.
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}
	return TRUE;
}

// The following functions are actually defined in BaseClasses, but we need to give their
// function signature here so we can call them correctly.
extern "C" void __cdecl __security_init_cookie(void);
extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);

// DLL Entry Point for DirectShow filters.
DECLSPEC_NOINLINE
BOOL
WINAPI
DllEntryPoint(
    HINSTANCE hInstance,
    ULONG ulReason,
    __inout_opt LPVOID pv
    )
{
    if ( ulReason == DLL_PROCESS_ATTACH ) {
        // Must happen before any other code is executed.  Thankfully - it's re-entrant
        __security_init_cookie();
    }

    return _DllEntryPoint(hInstance, ulReason, pv);
}

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

//------------------------------------------------------------------------------
// To be self registering, OLE servers must export functions named
// DllRegisterServer and DllUnregisterServer. These are the functions that are
// called when RegSrv32.exe is run.

STDAPI DllRegisterServer()
{
	DXSubFilter::WriteFilterConfigurationDataToRegistry();
	return AMovieDllRegisterServer2(TRUE);
}

STDAPI DllUnregisterServer()
{
	DXSubFilter::RemoveFilterConfigurationDataFromRegistry();
	return AMovieDllRegisterServer2(FALSE);
}

<commit_msg>Fixed filter not registering correctly. Fucking undocumented Microsoft behaviour.<commit_after>// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "registryhelpers.h"
#include "dxsubfilter_uuids.h"
#include "dxsubfilter.h"

//------------------------------------------------------------------------------
// Global filter information for proper DirectShow registration

AMOVIESETUP_MEDIATYPE sudVideoMediaTypes[] = {
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_AYUV },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_YUY2 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_YV12 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_NV12 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P210 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P216 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P010 },
	{ &MEDIATYPE_Video, &MEDIASUBTYPE_P016 },
};

AMOVIESETUP_MEDIATYPE sudSubtitleMediaTypes[] = {
	{ &MEDIATYPE_Text, &MEDIASUBTYPE_None },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_UTF8 },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_SSA },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_ASS },
	{ &MEDIATYPE_Subtitle, &MEDIASUBTYPE_VOBSUB },
};

AMOVIESETUP_PIN sudOutputPin = {
    L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    TRUE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudVideoMediaTypes),      // Number of media types.
    sudVideoMediaTypes					// Pointer to media types.
};

AMOVIESETUP_PIN sudInputVideoPin = {
	L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    FALSE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudVideoMediaTypes),      // Number of media types.
    sudVideoMediaTypes					// Pointer to media types.
};

AMOVIESETUP_PIN sudInputSubtitlePin = {
	L"",								// Obsolete, not used.
    FALSE,								// Is this pin rendered?
    FALSE,								// Is it an output pin?
    FALSE,								// Can the filter create zero instances?
    FALSE,								// Does the filter create multiple instances?
    &GUID_NULL,							// Obsolete.
    NULL,								// Obsolete.
    ARRAYSIZE(sudSubtitleMediaTypes),   // Number of media types.
    sudSubtitleMediaTypes				// Pointer to media types.
};

AMOVIESETUP_PIN sudDXSubFilterPins[] = {
	sudInputVideoPin,
	sudInputSubtitlePin,
	sudOutputPin,
};

AMOVIESETUP_FILTER sudDXSubFilterReg = {
    &CLSID_DXSubFilter,				// Filter CLSID.
	L"DXSubFilter",					// Filter name.
    MERIT_NORMAL,					// Merit.
	ARRAYSIZE(sudDXSubFilterPins),	// Number of pin types.
    sudDXSubFilterPins				// Pointer to pin information.
};
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
/* List of class IDs and creator functions for the class factory. This
   provides the link between the OLE entry point in the DLL and an object
   being created. The class factory will call the static CreateInstance
   function when it is asked to create a CLSID_DXSubFilter object */

CFactoryTemplate g_Templates[1] = {
    {
		L"CDXSubFilter",							// Name
		&CLSID_DXSubFilter,							// CLSID
		DXSubFilter::CDXSubFilter::CreateInstance,	// Creation function
		NULL,										// Initialization function (optional)
		&sudDXSubFilterReg							// Pointer to filter information
	}
};

int g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// The following functions are actually defined in BaseClasses, but we need to give their
// function signature here so we can call them correctly.
extern "C" void __cdecl __security_init_cookie(void);
extern "C" BOOL WINAPI _DllEntryPoint(HINSTANCE, ULONG, __inout_opt LPVOID);

// DLL Entry Point for DirectShow filters.
DECLSPEC_NOINLINE
BOOL
WINAPI
DllEntryPoint(
    HINSTANCE hInstance,
    ULONG ulReason,
    __inout_opt LPVOID pv
    )
{
    if ( ulReason == DLL_PROCESS_ATTACH ) {
        // Must happen before any other code is executed.  Thankfully - it's re-entrant
        __security_init_cookie();
    }

    return _DllEntryPoint(hInstance, ulReason, pv);
}

//	DLL Entry Point	for normal DLLs.
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
		break;
	case DLL_THREAD_ATTACH:
		break;
	case DLL_THREAD_DETACH:
		break;
	case DLL_PROCESS_DETACH:
		break;
	}

	// Microsoft DirectShow fail: DllMain is actually called by RegSvr32, but we need to run
	// DllEntryPoint to run the proper DirectShow specific stuff. Consequently, we need to
	// manually call DllEntryPoint ourselves. This solves the problem of our filter registering
	// incorrectly as RegSvr32.exe instead of itself.
	return DllEntryPoint(reinterpret_cast<HINSTANCE>(hModule), ul_reason_for_call, lpReserved);
}

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

//------------------------------------------------------------------------------
// To be self registering, OLE servers must export functions named
// DllRegisterServer and DllUnregisterServer. These are the functions that are
// called when RegSrv32.exe is run.

STDAPI DllRegisterServer()
{
	DXSubFilter::WriteFilterConfigurationDataToRegistry();
	return AMovieDllRegisterServer2(TRUE);
}

STDAPI DllUnregisterServer()
{
	DXSubFilter::RemoveFilterConfigurationDataFromRegistry();
	return AMovieDllRegisterServer2(FALSE);
}

<|endoftext|>


<commit_before>#include "gateway.h"
#include "type.pb.h"

#include <boost/thread/locks.hpp>
#include <ctime>
#include <iostream>
#include <google/protobuf/descriptor.h>
#include "interface.h"
#include <curlpp/Exception.hpp>
#include <log4cplus/logger.h>

Worker::Worker(Pool &){
    register_api("/query", boost::bind(&Worker::handle, this, _1, _2), "traite les requétes");
    register_api("/load", boost::bind(&Worker::load, this, _1, _2), "traite les requétes");
    register_api("/register", boost::bind(&Worker::register_navitia, this, _1, _2), "ajout d'un NAViTiA au pool");
    register_api("/status", boost::bind(&Worker::status, this, _1, _2), "status");
    register_api("/unregister", boost::bind(&Worker::unregister_navitia, this, _1, _2), "suppression d'un NAViTiA du pool");

}

webservice::ResponseData Worker::status(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;
    Context context;

    render_status(request, rd, context, pool);

    return rd;
}

webservice::ResponseData Worker::register_navitia(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;
    int thread = 8;

    if(request.params.find("url") == request.params.end()){
        rd.status_code = 500;
        return rd;
    }
    auto it = request.params.find("thread");
    if(it != request.params.end()){
        thread = atoi(it->second.c_str());
    }

    //TODO valider l'url
    pool.add_navitia(new Navitia(request.params["url"], thread));

    return status(request, pool);
}

webservice::ResponseData Worker::unregister_navitia(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;

    if(request.params.find("url") == request.params.end()){
        rd.status_code = 500;
        return rd;
    }

    //TODO valider l'url
    pool.remove_navitia(Navitia(request.params["url"], 8));

    return status(request, pool);
}

webservice::ResponseData Worker::handle(webservice::RequestData& request, Pool& pool){
    pool.check_desactivated_navitia();
    webservice::ResponseData rd;
    Context context;
    dispatcher(request, rd, pool, context);
    render(request, rd, context);
    return rd;
}

webservice::ResponseData Worker::load(webservice::RequestData& request, Pool& pool){
    //TODO gestion de la desactivation
    BOOST_FOREACH(Navitia* nav, pool.navitia_list){
        nav->load();
    }
    return this->status(request, pool);
}

void Dispatcher::operator()(webservice::RequestData& request, webservice::ResponseData& response, Pool& pool, Context& context){
    std::pair<int, std::string> res;
    int nb_try = 0;
    bool ok = true;
    do{
        ok = true;
        nb_try++;
        Navitia* nav = pool.next();
        try{
            res = nav->query(request.path.substr(request.path.find_last_of('/')) + "?" + request.raw_params);
            pool.release_navitia(nav);
        }catch(long& code){
            ok = false;
            nav->on_error();
            log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("logger"));
            LOG4CPLUS_WARN(logger, "la requétes a échouer");
            pool.release_navitia(nav);
            response.status_code = code;
            continue;
        }
        std::unique_ptr<pbnavitia::PTRefResponse> resp(new pbnavitia::PTRefResponse());
        if(resp->ParseFromString(res.second)){
            context.pb = std::move(resp);
            context.service = Context::PTREF;
        }else{
            ok = false;
            nav->on_error();
            log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("logger"));
            LOG4CPLUS_WARN(logger, "erreur de chargement du protobuf");
            context.str = res.second;
            context.service = Context::BAD_RESPONSE;
            response.status_code = res.first;
        }
    }while(!ok && nb_try < 4);
}

MAKE_WEBSERVICE(Pool, Worker)
<commit_msg>gestion des erreurs de ptref<commit_after>#include "gateway.h"
#include "type.pb.h"

#include <boost/thread/locks.hpp>
#include <ctime>
#include <iostream>
#include <google/protobuf/descriptor.h>
#include "interface.h"
#include <curlpp/Exception.hpp>
#include <log4cplus/logger.h>

Worker::Worker(Pool &){
    register_api("/query", boost::bind(&Worker::handle, this, _1, _2), "traite les requétes");
    register_api("/load", boost::bind(&Worker::load, this, _1, _2), "traite les requétes");
    register_api("/register", boost::bind(&Worker::register_navitia, this, _1, _2), "ajout d'un NAViTiA au pool");
    register_api("/status", boost::bind(&Worker::status, this, _1, _2), "status");
    register_api("/unregister", boost::bind(&Worker::unregister_navitia, this, _1, _2), "suppression d'un NAViTiA du pool");

}

webservice::ResponseData Worker::status(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;
    Context context;

    render_status(request, rd, context, pool);

    return rd;
}

webservice::ResponseData Worker::register_navitia(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;
    int thread = 8;

    if(request.params.find("url") == request.params.end()){
        rd.status_code = 500;
        return rd;
    }
    auto it = request.params.find("thread");
    if(it != request.params.end()){
        thread = atoi(it->second.c_str());
    }

    //TODO valider l'url
    pool.add_navitia(new Navitia(request.params["url"], thread));

    return status(request, pool);
}

webservice::ResponseData Worker::unregister_navitia(webservice::RequestData& request, Pool& pool){
    webservice::ResponseData rd;

    if(request.params.find("url") == request.params.end()){
        rd.status_code = 500;
        return rd;
    }

    //TODO valider l'url
    pool.remove_navitia(Navitia(request.params["url"], 8));

    return status(request, pool);
}

webservice::ResponseData Worker::handle(webservice::RequestData& request, Pool& pool){
    pool.check_desactivated_navitia();
    webservice::ResponseData rd;
    Context context;
    dispatcher(request, rd, pool, context);
    render(request, rd, context);
    return rd;
}

webservice::ResponseData Worker::load(webservice::RequestData& request, Pool& pool){
    //TODO gestion de la desactivation
    BOOST_FOREACH(Navitia* nav, pool.navitia_list){
        nav->load();
    }
    return this->status(request, pool);
}

void Dispatcher::operator()(webservice::RequestData& request, webservice::ResponseData& response, Pool& pool, Context& context){
    std::pair<int, std::string> res;
    int nb_try = 0;
    bool ok = true;
    do{
        ok = true;
        nb_try++;
        Navitia* nav = pool.next();
        try{
            res = nav->query(request.path.substr(request.path.find_last_of('/')) + "?" + request.raw_params);
            pool.release_navitia(nav);
        }catch(long& code){
            ok = false;
            nav->on_error();
            log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("logger"));
            LOG4CPLUS_WARN(logger, "la requétes a échouer");
            pool.release_navitia(nav);
            response.status_code = code;
            continue;
        }
        std::unique_ptr<pbnavitia::PTRefResponse> resp(new pbnavitia::PTRefResponse());
        if(resp->ParseFromString(res.second)){
            if(resp->has_error()){
                ok = false;
                nav->on_error();
                context.str = resp->error();
                context.service = Context::BAD_RESPONSE;
                continue;
            }
            context.pb = std::move(resp);
            context.service = Context::PTREF;
        }else{
            ok = false;
            nav->on_error();
            log4cplus::Logger logger = log4cplus::Logger::getInstance(LOG4CPLUS_TEXT("logger"));
            LOG4CPLUS_WARN(logger, "erreur de chargement du protobuf");
            context.str = res.second;
            context.service = Context::BAD_RESPONSE;
            response.status_code = res.first;
        }
    }while(!ok && nb_try < 4);
}

MAKE_WEBSERVICE(Pool, Worker)
<|endoftext|>


<commit_before>/***************************************************************************//**
 * FILE : block_array.hpp
 *
 * Implements an array container allocated in blocks.
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#if !defined (BLOCK_ARRAY_HPP)
#define BLOCK_ARRAY_HPP

#include "general/debug.h"

template <typename IndexType, typename EntryType, int blockLength = 256 >
	class block_array
{
private:
	// Note: any new attributes must be handled by swap()
	EntryType **blocks;
	IndexType blockCount;

	EntryType* getOrCreateBlock(IndexType blockIndex)
	{
		if (blockIndex >= blockCount)
		{
			IndexType newBlockCount = blockIndex + 1;
			if (newBlockCount < blockCount*2)
			{
				newBlockCount = blockCount*2;
			}
			EntryType **newBlocks;
			if (!REALLOCATE(newBlocks, blocks, EntryType *, newBlockCount))
				return NULL;
			for (IndexType i = blockCount; i < newBlockCount; i++)
			{
				newBlocks[i] = NULL;
			}
			blocks = newBlocks;
			blockCount = newBlockCount;
		}
		EntryType *block = blocks[blockIndex];
		if (!block)
		{
			if (ALLOCATE(block, EntryType, blockLength))
			{
				for (IndexType i = 0; i < blockLength; i++)
				{
					block[i] = 0; // only works for numeric or pointer types
				}
				blocks[blockIndex] = block;
			}
		}
		return block;
	}

public:

	block_array() :
		blocks(NULL),
		blockCount(0)
	{
	}

	~block_array()
	{
		clear();
	}

	void clear()
	{
		for (IndexType i = 0; i < blockCount; i++)
		{
			if (blocks[i])
			{
				DEALLOCATE(blocks[i]);
			}
		}
		if (blocks)
		{
			DEALLOCATE(blocks);
		}
		blockCount = 0;
	}

	/** Swaps all data with other block_array. Cannot fail. */
	void swap(block_array& other)
	{
		EntryType **temp_blocks = blocks;
		IndexType temp_blockCount = blockCount;
		blocks = other.blocks;
		blockCount = other.blockCount;
		other.blocks = temp_blocks;
		other.blockCount = temp_blockCount;
	}

	/**
	 * Get a value from the block_array.
	 * @param index  The index of the value to retrieve, starting at 0.
	 * @param value  On success, filled with value held at index.
	 * @return  1 if value returned, 0 if no value at index.
	 */
	int getValue(IndexType index, EntryType& value) const
	{
		IndexType blockIndex = index / blockLength;
		if (blockIndex < blockCount)
		{
			EntryType *block = blocks[blockIndex];
			if (block)
			{
				IndexType entryIndex = index % blockLength;
				value = block[entryIndex];
				return 1;
			}
		}
		return 0;
	}

	/**
	 * Set a value in the block_array.
	 * @param index  The index of the value to set, starting at 0.
	 * @param value  Value to set at index.
	 * @return  1 if value set, 0 if failed.
	 */
	int setValue(IndexType index, EntryType value)
	{
		IndexType blockIndex = index / blockLength;
		EntryType* block = getOrCreateBlock(blockIndex);
		if (!block)
			return 0;
		IndexType entryIndex = index % blockLength;
		block[entryIndex] = value;
		return 1;
	}

	bool setValues(IndexType minIndex, IndexType maxIndex, EntryType value)
	{
		// GRC: can be made faster
		for (IndexType index = minIndex; index <= maxIndex; index++)
		{
			if (!setValue(index, value))
				return false;
		}
		return true;
	}

};

/** stores boolean values as individual bits, with no value equivalent to false */
template <typename IndexType, int intBlockLength = 32>
	class bool_array : private block_array<IndexType, unsigned int, intBlockLength>
{
public:
	void clear()
	{
		block_array<IndexType, unsigned int, intBlockLength>::clear();
	}

	void swap(bool_array& other)
	{
		block_array<IndexType, unsigned int, intBlockLength>::swap(other);
	}

	/** @param oldValue  Returns old value so client can determine if status changed */
	int setBool(IndexType index, bool value, bool& oldValue)
	{
		IndexType intIndex = index >> 5;
		unsigned int intValue = 0;
		int hasValue = getValue(intIndex, intValue);
		if (hasValue || value)
		{
			unsigned int mask = (1 << (index & 0x1F));
			oldValue = (0 != (intValue & mask));
			if (oldValue != value)
			{
				return setValue(intIndex, intValue ^ mask);
			}
		}
		else
		{
			oldValue = false;
		}
		return 1;
	}

	bool getBool(IndexType index) const
	{
		IndexType intIndex = index >> 5;
		unsigned int intValue = 0;
		if (getValue(intIndex, intValue))
		{
			unsigned int mask = (1 << (index & 0x1F));
			return (0 != (intValue & mask));
		}
		return false;
	}

	/**
	 * @param lastTrueIndex  Updated to equal or next lower index with true value.
	 * @return  true if found, false if none.
	 */
	bool updateLastTrueIndex(IndexType& lastTrueIndex)
	{
		// GRC this can be made much more efficient
		while (!getBool(lastTrueIndex))
		{
			--lastTrueIndex;
			if (lastTrueIndex < 0)
				return false;
		}
		return true;
	}

	/** @return  true if values for all indexes in range are true; false otherwise */
	bool isRangeTrue(IndexType minIndex, IndexType maxIndex)
	{
		if (minIndex > maxIndex)
			return false;
		// GRC this can be made much more efficient
		IndexType index = minIndex;
		while (getBool(index))
		{
			if (index == maxIndex)
				return true;
			index++;
		}
		return false;
	}

	/** Sets all entries from index 0..indexCount-1 to true.
	 * @return  true if completely successful, false otherwise */
	bool setAllTrue(IndexType indexCount)
	{
		IndexType intIndexCount = indexCount >> 5;
		// bulk set the flags in lots of 32 bits
		if (!setValues(0, intIndexCount-1, 0xFFFFFFFF))
			return false;
		// individually set remaining bits
		for (IndexType index = intIndexCount*32; index < indexCount; index++)
		{
			bool oldValue;
			if (!setBool(index, true, oldValue))
				return false;
		}
		return true;
	}
};

#endif /* !defined (BLOCK_ARRAY_HPP) */
<commit_msg>Compilation fixes for gcc 4.7.1.<commit_after>/***************************************************************************//**
 * FILE : block_array.hpp
 *
 * Implements an array container allocated in blocks.
 */
/* ***** BEGIN LICENSE BLOCK *****
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * The contents of this file are subject to the Mozilla Public 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.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is cmgui.
 *
 * The Initial Developer of the Original Code is
 * Auckland Uniservices Ltd, Auckland, New Zealand.
 * Portions created by the Initial Developer are Copyright (C) 2010
 * the Initial Developer. All Rights Reserved.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 * in which case the provisions of the GPL or the LGPL are applicable instead
 * of those above. If you wish to allow use of your version of this file only
 * under the terms of either the GPL or the LGPL, and not to allow others to
 * use your version of this file under the terms of the MPL, indicate your
 * decision by deleting the provisions above and replace them with the notice
 * and other provisions required by the GPL or the LGPL. If you do not delete
 * the provisions above, a recipient may use your version of this file under
 * the terms of any one of the MPL, the GPL or the LGPL.
 *
 * ***** END LICENSE BLOCK ***** */

#if !defined (BLOCK_ARRAY_HPP)
#define BLOCK_ARRAY_HPP

#include "general/debug.h"

template <typename IndexType, typename EntryType, int blockLength = 256 >
	class block_array
{
private:
	// Note: any new attributes must be handled by swap()
	EntryType **blocks;
	IndexType blockCount;

	EntryType* getOrCreateBlock(IndexType blockIndex)
	{
		if (blockIndex >= blockCount)
		{
			IndexType newBlockCount = blockIndex + 1;
			if (newBlockCount < blockCount*2)
			{
				newBlockCount = blockCount*2;
			}
			EntryType **newBlocks;
			if (!REALLOCATE(newBlocks, blocks, EntryType *, newBlockCount))
				return NULL;
			for (IndexType i = blockCount; i < newBlockCount; i++)
			{
				newBlocks[i] = NULL;
			}
			blocks = newBlocks;
			blockCount = newBlockCount;
		}
		EntryType *block = blocks[blockIndex];
		if (!block)
		{
			if (ALLOCATE(block, EntryType, blockLength))
			{
				for (IndexType i = 0; i < blockLength; i++)
				{
					block[i] = 0; // only works for numeric or pointer types
				}
				blocks[blockIndex] = block;
			}
		}
		return block;
	}

public:

	block_array() :
		blocks(NULL),
		blockCount(0)
	{
	}

	~block_array()
	{
		clear();
	}

	void clear()
	{
		for (IndexType i = 0; i < blockCount; i++)
		{
			if (blocks[i])
			{
				DEALLOCATE(blocks[i]);
			}
		}
		if (blocks)
		{
			DEALLOCATE(blocks);
		}
		blockCount = 0;
	}

	/** Swaps all data with other block_array. Cannot fail. */
	void swap(block_array& other)
	{
		EntryType **temp_blocks = blocks;
		IndexType temp_blockCount = blockCount;
		blocks = other.blocks;
		blockCount = other.blockCount;
		other.blocks = temp_blocks;
		other.blockCount = temp_blockCount;
	}

	/**
	 * Get a value from the block_array.
	 * @param index  The index of the value to retrieve, starting at 0.
	 * @param value  On success, filled with value held at index.
	 * @return  1 if value returned, 0 if no value at index.
	 */
	int getValue(IndexType index, EntryType& value) const
	{
		IndexType blockIndex = index / blockLength;
		if (blockIndex < blockCount)
		{
			EntryType *block = blocks[blockIndex];
			if (block)
			{
				IndexType entryIndex = index % blockLength;
				value = block[entryIndex];
				return 1;
			}
		}
		return 0;
	}

	/**
	 * Set a value in the block_array.
	 * @param index  The index of the value to set, starting at 0.
	 * @param value  Value to set at index.
	 * @return  1 if value set, 0 if failed.
	 */
	int setValue(IndexType index, EntryType value)
	{
		IndexType blockIndex = index / blockLength;
		EntryType* block = getOrCreateBlock(blockIndex);
		if (!block)
			return 0;
		IndexType entryIndex = index % blockLength;
		block[entryIndex] = value;
		return 1;
	}

	bool setValues(IndexType minIndex, IndexType maxIndex, EntryType value)
	{
		// GRC: can be made faster
		for (IndexType index = minIndex; index <= maxIndex; index++)
		{
			if (!setValue(index, value))
				return false;
		}
		return true;
	}

};

/** stores boolean values as individual bits, with no value equivalent to false */
template <typename IndexType, int intBlockLength = 32>
	class bool_array : private block_array<IndexType, unsigned int, intBlockLength>
{
public:
	void clear()
	{
		block_array<IndexType, unsigned int, intBlockLength>::clear();
	}

	void swap(bool_array& other)
	{
		block_array<IndexType, unsigned int, intBlockLength>::swap(other);
	}

	using block_array<IndexType, unsigned int, intBlockLength>::getValue;
	using block_array<IndexType, unsigned int, intBlockLength>::setValue;
	using block_array<IndexType, unsigned int, intBlockLength>::setValues;

	/** @param oldValue  Returns old value so client can determine if status changed */
	int setBool(IndexType index, bool value, bool& oldValue)
	{
		IndexType intIndex = index >> 5;
		unsigned int intValue = 0;
		int hasValue = getValue(intIndex, intValue);
		if (hasValue || value)
		{
			unsigned int mask = (1 << (index & 0x1F));
			oldValue = (0 != (intValue & mask));
			if (oldValue != value)
			{
				return setValue(intIndex, intValue ^ mask);
			}
		}
		else
		{
			oldValue = false;
		}
		return 1;
	}

	bool getBool(IndexType index) const
	{
		IndexType intIndex = index >> 5;
		unsigned int intValue = 0;
		if (getValue(intIndex, intValue))
		{
			unsigned int mask = (1 << (index & 0x1F));
			return (0 != (intValue & mask));
		}
		return false;
	}

	/**
	 * @param lastTrueIndex  Updated to equal or next lower index with true value.
	 * @return  true if found, false if none.
	 */
	bool updateLastTrueIndex(IndexType& lastTrueIndex)
	{
		// GRC this can be made much more efficient
		while (!getBool(lastTrueIndex))
		{
			--lastTrueIndex;
			if (lastTrueIndex < 0)
				return false;
		}
		return true;
	}

	/** @return  true if values for all indexes in range are true; false otherwise */
	bool isRangeTrue(IndexType minIndex, IndexType maxIndex)
	{
		if (minIndex > maxIndex)
			return false;
		// GRC this can be made much more efficient
		IndexType index = minIndex;
		while (getBool(index))
		{
			if (index == maxIndex)
				return true;
			index++;
		}
		return false;
	}

	/** Sets all entries from index 0..indexCount-1 to true.
	 * @return  true if completely successful, false otherwise */
	bool setAllTrue(IndexType indexCount)
	{
		IndexType intIndexCount = indexCount >> 5;
		// bulk set the flags in lots of 32 bits
		if (!setValues(0, intIndexCount-1, 0xFFFFFFFF))
			return false;
		// individually set remaining bits
		for (IndexType index = intIndexCount*32; index < indexCount; index++)
		{
			bool oldValue;
			if (!setBool(index, true, oldValue))
				return false;
		}
		return true;
	}
};

#endif /* !defined (BLOCK_ARRAY_HPP) */
<|endoftext|>


<commit_before>/*
 * Copyright 2015 Aldebaran
 *
 * 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 <iostream>

#include <kdl_parser/kdl_parser.hpp>
#include <kdl/tree.hpp>
#include <tf/transform_datatypes.h>
#include <robot_state_publisher/robot_state_publisher.h>

#include "joint_state.hpp"

namespace alros
{
namespace publisher
{

JointStatePublisher::JointStatePublisher( const std::string& name, const std::string& topic, float frequency, qi::SessionPtr& session ):
  BasePublisher( name, topic, frequency, session ),
  p_motion_( session->service("ALMotion") )
{}

void JointStatePublisher::publish()
{
  // get joint state values
  std::vector<float> al_joint_angles = p_motion_.call<std::vector<float> >("getAngles", "JointActuators", true );
  msg_joint_states_.header.stamp = ros::Time::now();
  // STUPID CONVERTION FROM FLOAT TO DOUBLE ARRAY --> OPTIMIZE THAT!
  msg_joint_states_.position = std::vector<double>( al_joint_angles.begin(), al_joint_angles.end() );
  pub_joint_states_.publish( msg_joint_states_ );

  // Leg might be an artificial joint in between all wheels of pepper
  std::vector<float> al_odometry_data = p_motion_.call<std::vector<float> >( "getRobotPosition", true );

  msg_nav_odom_.header.stamp = ros::Time::now();
  msg_tf_odom_.header.stamp = ros::Time::now();

  const float& odomX =  al_odometry_data[0];
  const float& odomY =  al_odometry_data[1];
  const float& odomTheta =  al_odometry_data[2];

  // we can improve this with a velocity computation as well
  // with this we simply set the velocity as the diff between (odomX - msg_odom_.pose.pose.position.x)/dt
  msg_nav_odom_.pose.pose.position.x = odomX;
  msg_nav_odom_.pose.pose.position.y = odomY;
  msg_nav_odom_.pose.pose.position.z = 0;
  msg_nav_odom_.pose.pose.orientation = tf::createQuaternionMsgFromRollPitchYaw( 0, 0, odomTheta );
  // fill in velocity components here
  pub_odom_.publish(msg_nav_odom_);

  // put joint states in tf broadcaster
  std::map< std::string, double > joint_state_map;
  // stupid version --> change this with std::transform c++11 ??!
  std::transform( msg_joint_states_.name.begin(), msg_joint_states_.name.end(), msg_joint_states_.position.begin(), std::inserter( joint_state_map, joint_state_map.end() ), std::make_pair<std::string, double>);

  static const std::string& jt_tf_prefix = "";
  rspPtr_->publishTransforms( joint_state_map, msg_joint_states_.header.stamp, jt_tf_prefix );
  rspPtr_->publishFixedTransforms( jt_tf_prefix );

  //const geometry_msgs::Point& p = msg_nav_odom_.pose.pose.position;
  //const geometry_msgs::Quaternion& q = msg_nav_odom_.pose.pose.orientation;
  //msg_tf_odom_.transform.translation.x = odomX;
  //msg_tf_odom_.transform.translation.y = odomY;
  //msg_tf_odom_.transform.translation.z = 0;
  //msg_tf_odom_.transform.rotation = msg_nav_odom_.pose.pose.orientation;

  // DEBUG
  static tf::Transform transform;
  transform.setOrigin( tf::Vector3(odomX, odomY, 0) );
  tf::Quaternion q;
  q.setRPY(0, 0, odomTheta);
  transform.setRotation(q);

  tf_br_.sendTransform( tf::StampedTransform(transform, msg_tf_odom_.header.stamp, "base_footprint", "odom" ) );
  //tf_br_.sendTransform( msg_tf_odom_ );
}

void JointStatePublisher::reset( ros::NodeHandle& nh )
{
  pub_joint_states_ = nh.advertise<sensor_msgs::JointState>( topic_, 10 );
  pub_odom_ = nh.advertise<nav_msgs::Odometry>( "/odom", 10 );

  // load urdf from param server (alternatively from file)
  if ( nh.hasParam("/robot_description") )
  {
    KDL::Tree tree;
    std::string robot_desc;
    nh.getParam("/robot_description", robot_desc);
    kdl_parser::treeFromString( robot_desc, tree );
    rspPtr_.reset( new robot_state_publisher::RobotStatePublisher(tree) );
  }
  else{
    std::cerr << "failed to load robot description in joint_state_publisher" << std::endl;
    is_initialized_ = false;
    return;
  }

  // pre-fill joint states message
  msg_joint_states_.name = p_motion_.call<std::vector<std::string> >("getBodyNames", "JointActuators" );

  // pre-fill odometry message
  msg_nav_odom_.header.frame_id = "odom";
  msg_nav_odom_.child_frame_id = "base_footprint";

  msg_tf_odom_.header.frame_id = "odom";
  msg_tf_odom_.child_frame_id = "base_footprint";

  is_initialized_ = true;
}

bool JointStatePublisher::isSubscribed() const
{
  // assume JS and TF as essential, so publish always
  return true;
}

} //publisher
} // alros
<commit_msg>correct odometry frame<commit_after>/*
 * Copyright 2015 Aldebaran
 *
 * 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 <iostream>

#include <kdl_parser/kdl_parser.hpp>
#include <kdl/tree.hpp>
#include <tf/transform_datatypes.h>
#include <robot_state_publisher/robot_state_publisher.h>

#include "joint_state.hpp"

namespace alros
{
namespace publisher
{

JointStatePublisher::JointStatePublisher( const std::string& name, const std::string& topic, float frequency, qi::SessionPtr& session ):
  BasePublisher( name, topic, frequency, session ),
  p_motion_( session->service("ALMotion") )
{}

void JointStatePublisher::publish()
{
  // get joint state values
  std::vector<float> al_joint_angles = p_motion_.call<std::vector<float> >("getAngles", "Body", true );
  // Leg might be an artificial joint in between all wheels of pepper
  std::vector<float> al_odometry_data = p_motion_.call<std::vector<float> >( "getPosition", "Torso", 1, true );
  const ros::Time& stamp = ros::Time::now();
  const float& odomX =  al_odometry_data[0];
  const float& odomY =  al_odometry_data[1];
  const float& odomZ =  al_odometry_data[2];
  const float& odomWX =  al_odometry_data[3];
  const float& odomWY =  al_odometry_data[4];
  const float& odomWZ =  al_odometry_data[5];
  //since all odometry is 6DOF we'll need a quaternion created from yaw
  geometry_msgs::Quaternion odom_quat = tf::createQuaternionMsgFromRollPitchYaw( odomWX, odomWY, odomWZ );

  /**
   * JOINT STATE PUBLISHER
   */
  msg_joint_states_.header.stamp = stamp;

  // STUPID CONVERTION FROM FLOAT TO DOUBLE ARRAY --> OPTIMIZE THAT!
  msg_joint_states_.position = std::vector<double>( al_joint_angles.begin(), al_joint_angles.end() );
  pub_joint_states_.publish( msg_joint_states_ );

  /**
   * ROBOT STATE PUBLISHER
   */
  // put joint states in tf broadcaster
  std::map< std::string, double > joint_state_map;
  // stupid version --> change this with std::transform c++11 ??!
  std::transform( msg_joint_states_.name.begin(), msg_joint_states_.name.end(), msg_joint_states_.position.begin(), std::inserter( joint_state_map, joint_state_map.end() ), std::make_pair<std::string, double>);

  static const std::string& jt_tf_prefix = "";
  rspPtr_->publishTransforms( joint_state_map, stamp, jt_tf_prefix );
  rspPtr_->publishFixedTransforms( jt_tf_prefix );

  /**
   * ODOMETRY FRAME
   */
  msg_tf_odom_.header.stamp = stamp+ros::Duration(0.5);

  msg_tf_odom_.transform.translation.x = odomX;
  msg_tf_odom_.transform.translation.y = odomY;
  msg_tf_odom_.transform.translation.z = odomZ;
  msg_tf_odom_.transform.rotation = odom_quat;

  tf_br_.sendTransform( msg_tf_odom_ );

  /**
   * ODOMETRY MESSAGE
   */
  // we can improve this with a velocity computation as well
  // with this we simply set the velocity as the diff between (odomX - msg_odom_.pose.pose.position.x)/dt
//  msg_nav_odom_.header.stamp = msg_tf_odom_.header.stamp;
//
//  msg_nav_odom_.pose.pose.position.x = odomX;
//  msg_nav_odom_.pose.pose.position.y = odomY;
//  msg_nav_odom_.pose.pose.position.z = 0;
//  msg_nav_odom_.pose.pose.orientation = odom_quat;
//  // fill in velocity components here
//  pub_odom_.publish(msg_nav_odom_);
}

void JointStatePublisher::reset( ros::NodeHandle& nh )
{
  pub_joint_states_ = nh.advertise<sensor_msgs::JointState>( topic_, 10 );
  pub_odom_ = nh.advertise<nav_msgs::Odometry>( "/odom", 10 );

  // load urdf from param server (alternatively from file)
  if ( nh.hasParam("/robot_description") )
  {
    KDL::Tree tree;
    std::string robot_desc;
    nh.getParam("/robot_description", robot_desc);
    kdl_parser::treeFromString( robot_desc, tree );
    rspPtr_.reset( new robot_state_publisher::RobotStatePublisher(tree) );
  }
  else{
    std::cerr << "failed to load robot description in joint_state_publisher" << std::endl;
    is_initialized_ = false;
    return;
  }

  // pre-fill joint states message
  msg_joint_states_.name = p_motion_.call<std::vector<std::string> >("getBodyNames", "Body" );

  msg_tf_odom_.header.frame_id = "odom";
  msg_tf_odom_.child_frame_id = "base_link";

  // pre-fill odometry message
  msg_nav_odom_.header.frame_id = "odom";
  msg_nav_odom_.child_frame_id = "base_footprint";

  is_initialized_ = true;
}

bool JointStatePublisher::isSubscribed() const
{
  // assume JS and TF as essential, so publish always
  return true;
}

} //publisher
} // alros
<|endoftext|>


<commit_before>/* Copyright (c) 2018 PaddlePaddle 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 <glog/logging.h>
#include <gtest/gtest.h>
#include "gflags/gflags.h"

#include "paddle/fluid/inference/tests/api/trt_test_helper.h"

namespace paddle {
namespace inference {

void run(const AnalysisConfig& config, std::vector<float>* out_data) {
  auto predictor = CreatePaddlePredictor(config);
  auto input_names = predictor->GetInputNames();

  int run_batch = 1;
  const int run_seq_len = 128;

  std::vector<int64_t> tmp_input;
  std::vector<float> tmp_four_input;
  tmp_input.reserve(run_batch * run_seq_len);
  tmp_four_input.reserve(run_batch * run_seq_len);

  int64_t i0[run_seq_len] = {
      1,    3558, 4,   75,  491, 89, 340, 313, 93,   4,   255,   10, 75,    321,
      4095, 1902, 4,   134, 49,  75, 311, 14,  44,   178, 543,   15, 12043, 2,
      75,   201,  340, 9,   14,  44, 486, 218, 1140, 279, 12043, 2};
  int64_t i1[run_seq_len] = {
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  int64_t i2[run_seq_len] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
                             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
                             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                             30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
  float i3[run_seq_len] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

  // first input
  auto input_t = predictor->GetInputTensor(input_names[0]);
  input_t->Reshape({run_batch, run_seq_len, 1});
  input_t->copy_from_cpu(i0);

  // second input
  auto input_t2 = predictor->GetInputTensor(input_names[1]);
  input_t2->Reshape({run_batch, run_seq_len, 1});
  input_t2->copy_from_cpu(i1);

  // third input.
  auto input_t3 = predictor->GetInputTensor(input_names[2]);
  input_t3->Reshape({run_batch, run_seq_len, 1});
  input_t3->copy_from_cpu(i2);

  auto input_t4 = predictor->GetInputTensor(input_names[3]);
  input_t4->Reshape({run_batch, run_seq_len, 1});
  input_t4->copy_from_cpu(i3);

  ASSERT_TRUE(predictor->ZeroCopyRun());

  auto output_names = predictor->GetOutputNames();
  auto output_t = predictor->GetOutputTensor(output_names[0]);
  std::vector<int> output_shape = output_t->shape();
  int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
                                std::multiplies<int>());
  out_data->resize(out_num);
  output_t->copy_to_cpu(out_data->data());
}

void trt_ernie(bool with_fp16, std::vector<float> result) {
  AnalysisConfig config;
  std::string model_dir = FLAGS_infer_model;
  SetConfig(&config, model_dir, true);

  config.SwitchUseFeedFetchOps(false);

  int batch = 32;
  int min_seq_len = 1;
  int max_seq_len = 128;
  int opt_seq_len = 128;

  std::vector<int> min_shape = {1, min_seq_len, 1};
  std::vector<int> max_shape = {batch, max_seq_len, 1};
  std::vector<int> opt_shape = {batch, opt_seq_len, 1};
  // Set the input's min, max, opt shape
  std::map<std::string, std::vector<int>> min_input_shape = {
      {"read_file_0.tmp_0", min_shape},
      {"read_file_0.tmp_1", min_shape},
      {"read_file_0.tmp_2", min_shape},
      {"read_file_0.tmp_3", min_shape}};
  std::map<std::string, std::vector<int>> max_input_shape = {
      {"read_file_0.tmp_0", max_shape},
      {"read_file_0.tmp_1", max_shape},
      {"read_file_0.tmp_2", max_shape},
      {"read_file_0.tmp_3", max_shape}};
  std::map<std::string, std::vector<int>> opt_input_shape = {
      {"read_file_0.tmp_0", opt_shape},
      {"read_file_0.tmp_1", opt_shape},
      {"read_file_0.tmp_2", opt_shape},
      {"read_file_0.tmp_3", opt_shape}};

  auto precision = AnalysisConfig::Precision::kFloat32;
  if (with_fp16) {
    precision = AnalysisConfig::Precision::kHalf;
  }
  config.EnableTensorRtEngine(1 << 30, 1, 12, precision, false, false);
  config.SetTRTDynamicShapeInfo(min_input_shape, max_input_shape,
                                opt_input_shape);
  std::vector<float> out_data;
  run(config, &out_data);

  for (size_t i = 0; i < out_data.size(); i++) {
    EXPECT_NEAR(result[i], out_data[i], 2e-3);
  }
}

TEST(AnalysisPredictor, no_fp16) {
  std::vector<float> result = {0.498667, 0.501333};
  trt_ernie(false, result);
}

}  // namespace inference
}  // namespace paddle
<commit_msg>Fix wrong inputs (#39700)<commit_after>/* Copyright (c) 2018 PaddlePaddle 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 <glog/logging.h>
#include <gtest/gtest.h>
#include "gflags/gflags.h"

#include "paddle/fluid/inference/tests/api/trt_test_helper.h"

namespace paddle {
namespace inference {

void run(const AnalysisConfig& config, std::vector<float>* out_data) {
  auto predictor = CreatePaddlePredictor(config);
  auto input_names = predictor->GetInputNames();

  int run_batch = 1;
  const int run_seq_len = 128;

  std::vector<int64_t> tmp_input;
  std::vector<float> tmp_four_input;
  tmp_input.reserve(run_batch * run_seq_len);
  tmp_four_input.reserve(run_batch * run_seq_len);

  int64_t i0[run_seq_len] = {
      1,    3558, 4,   75,  491, 89, 340, 313, 93,   4,   255,   10, 75,    321,
      4095, 1902, 4,   134, 49,  75, 311, 14,  44,   178, 543,   15, 12043, 2,
      75,   201,  340, 9,   14,  44, 486, 218, 1140, 279, 12043, 2};
  int64_t i1[run_seq_len] = {0,  1,  2,  3,  4,  5,  6,  7,  8,  9,
                             10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
                             20, 21, 22, 23, 24, 25, 26, 27, 28, 29,
                             30, 31, 32, 33, 34, 35, 36, 37, 38, 39};
  int64_t i2[run_seq_len] = {
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  float i3[run_seq_len] = {1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,
                           1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0};

  // first input
  auto input_t = predictor->GetInputTensor(input_names[0]);
  input_t->Reshape({run_batch, run_seq_len, 1});
  input_t->copy_from_cpu(i0);

  // second input
  auto input_t2 = predictor->GetInputTensor(input_names[1]);
  input_t2->Reshape({run_batch, run_seq_len, 1});
  input_t2->copy_from_cpu(i1);

  // third input.
  auto input_t3 = predictor->GetInputTensor(input_names[2]);
  input_t3->Reshape({run_batch, run_seq_len, 1});
  input_t3->copy_from_cpu(i2);

  auto input_t4 = predictor->GetInputTensor(input_names[3]);
  input_t4->Reshape({run_batch, run_seq_len, 1});
  input_t4->copy_from_cpu(i3);

  ASSERT_TRUE(predictor->ZeroCopyRun());

  auto output_names = predictor->GetOutputNames();
  auto output_t = predictor->GetOutputTensor(output_names[0]);
  std::vector<int> output_shape = output_t->shape();
  int out_num = std::accumulate(output_shape.begin(), output_shape.end(), 1,
                                std::multiplies<int>());
  out_data->resize(out_num);
  output_t->copy_to_cpu(out_data->data());
}

void trt_ernie(bool with_fp16, std::vector<float> result) {
  AnalysisConfig config;
  std::string model_dir = FLAGS_infer_model;
  SetConfig(&config, model_dir, true);

  config.SwitchUseFeedFetchOps(false);

  int batch = 32;
  int min_seq_len = 1;
  int max_seq_len = 128;
  int opt_seq_len = 128;

  std::vector<int> min_shape = {1, min_seq_len, 1};
  std::vector<int> max_shape = {batch, max_seq_len, 1};
  std::vector<int> opt_shape = {batch, opt_seq_len, 1};
  // Set the input's min, max, opt shape
  std::map<std::string, std::vector<int>> min_input_shape = {
      {"read_file_0.tmp_0", min_shape},
      {"read_file_0.tmp_1", min_shape},
      {"read_file_0.tmp_2", min_shape},
      {"read_file_0.tmp_3", min_shape}};
  std::map<std::string, std::vector<int>> max_input_shape = {
      {"read_file_0.tmp_0", max_shape},
      {"read_file_0.tmp_1", max_shape},
      {"read_file_0.tmp_2", max_shape},
      {"read_file_0.tmp_3", max_shape}};
  std::map<std::string, std::vector<int>> opt_input_shape = {
      {"read_file_0.tmp_0", opt_shape},
      {"read_file_0.tmp_1", opt_shape},
      {"read_file_0.tmp_2", opt_shape},
      {"read_file_0.tmp_3", opt_shape}};

  auto precision = AnalysisConfig::Precision::kFloat32;
  if (with_fp16) {
    precision = AnalysisConfig::Precision::kHalf;
  }
  config.EnableTensorRtEngine(1 << 30, 1, 12, precision, false, false);
  config.SetTRTDynamicShapeInfo(min_input_shape, max_input_shape,
                                opt_input_shape);
  std::vector<float> out_data;
  run(config, &out_data);

  for (size_t i = 0; i < out_data.size(); i++) {
    EXPECT_NEAR(result[i], out_data[i], 2e-3);
  }
}

TEST(AnalysisPredictor, no_fp16) {
  std::vector<float> result = {0.498667, 0.501333};
  trt_ernie(false, result);
}

}  // namespace inference
}  // namespace paddle
<|endoftext|>


<commit_before>#pragma once
//=====================================================================//
/*!	@file
	@brief	MAX7219 ドライバー
			Copyright 2016 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include <cstring>
#include "common/iica_io.hpp"
#include "common/time.h"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  MAX7219 テンプレートクラス
		@param[in]	SPI		SPI クラス
		@param[in]	SELECT	デバイス選択
		@param[in]	CHAIN	デージー・チェイン数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class SPI, class SELECT, uint32_t CHAIN = 1>
	class MAX7219 {

		SPI&		spi_;

		uint16_t	limit_;
		uint8_t		data_[CHAIN * 8];

		enum class command : uint8_t {
			NO_OP        = 0x00,
			DIGIT_0      = 0x01,
			DIGIT_1      = 0x02,
			DIGIT_2      = 0x03,
			DIGIT_3      = 0x04,
			DIGIT_4      = 0x05,
			DIGIT_5      = 0x06,
			DIGIT_6      = 0x07,
			DIGIT_7      = 0x08,
			DECODE_MODE  = 0x09,
			INTENSITY    = 0x0A,
			SCAN_LIMIT   = 0x0B,
			SHUTDOWN     = 0x0C,
			DISPLAY_TEST = 0x0F,
		};

		// MAX7212 MSB first, 2 bytes
		void out_(command cmd, uint8_t dat) {
			SELECT::P = 0;
			uint8_t tmp[2];
			tmp[0] = static_cast<uint8_t>(cmd);
			tmp[1] = dat;
			spi_.send(tmp, 2);
			SELECT::P = 1;  // load
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	spi	SPI クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		MAX7219(SPI& spi) : spi_(spi), limit_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@param[in]	limit	スキャン・リミット
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start(uint8_t limit = (CHAIN * 8)) {
			if(limit_ > (8 * CHAIN) || limit == 0) {
				return false;
			}
			limit_ = limit;

			SELECT::DIR = 1;  // output;
			SELECT::PU  = 0;  // pull-up disable
			SELECT::P = 1;    // /CS = H

			for(uint8_t i = 0; i < sizeof(data_); ++i) {
				data_[i] = 0;
			}

			out_(command::SHUTDOWN, 0x01);  // ノーマル・モード
			out_(command::DECODE_MODE, 0x00);  // デコード・モード
			out_(command::SCAN_LIMIT, limit - 1);  // 表示桁設定
			set_intensity(0);  // 輝度（最低）

			service();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 輝度の設定
			@param[in]	inten	輝度値（最小：０、最大：１５）
			@return エラー（初期化不良）なら「false」
		 */
		//-----------------------------------------------------------------//
		bool set_intensity(uint8_t inten) {
			if(limit_ == 0) return false;
			out_(command::INTENSITY, inten);
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief データ転送
			@return エラー（初期化不良）なら「false」
		 */
		//-----------------------------------------------------------------//
		bool service() {
			if(limit_ == 0) return false;

			for(uint8_t i = 0; i < limit_; ++i) {
				out_(static_cast<command>(static_cast<uint8_t>(command::DIGIT_0) + i), data_[i]);
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 値の取得
			@param[in]	idx	インデックス（０～７）
			@return 値
		 */
		//-----------------------------------------------------------------//
		uint8_t get(uint8_t idx) {
			if(idx < limit_) {
				return data_[idx];
			}
			return 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 値の設定
			@param[in]	idx	インデックス（０～７）
			@param[in]	dat	データ
		 */
		//-----------------------------------------------------------------//
		void set(uint8_t idx, uint8_t dat) {
			if(idx < limit_) {
				data_[idx] = dat;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief キャラクターの設定
			@param[in]	idx	インデックス（０～７）
			@param[in]	cha	キャラクターコード
			@param[in]	dp	小数点
		 */
		//-----------------------------------------------------------------//
		void set_cha(uint8_t idx, char cha, bool dp = false) {
			uint8_t d = 0;
			switch(cha) {
			case ' ':
				break;
			case '-':
				d = 0b0000001;
				break;
			case '_':
				d = 0b0001000;
				break;
			case '~':
				d = 0b1000000;
				break;
			case '0':
				d = 0b1111110;
				break;
			case '1':
				d = 0b0110000;
				break;
			case '2':
				d = 0b1101101;
				break;
			case '3':
				d = 0b1111001;
				break;
			case '4':
				d = 0b0110011;
				break;
			case '5':
				d = 0b1011011;
				break;
			case '6':
				d = 0b1011111;
				break;
			case '7':
				d = 0b1110000;
				break;
			case '8':
				d = 0b1111111;
				break;
			case '9':
				d = 0b1111011;
				break;
			case 'A':
			case 'a':
				d = 0b1110111;
				break;
			case 'B':
			case 'b':
				d = 0b0011111;
				break;
			case 'C':
				d = 0b1001110;
				break;
			case 'c':
				d = 0b0001101;
				break;
			case 'D':
			case 'd':
				d = 0b0111101;
				break;
			case 'E':
			case 'e':
				d = 0b1001111;
				break;
			case 'F':
			case 'f':
				d = 0b1000111;
				break;
			case 'G':
			case 'g':
				d = 0b1011110;
				break;
			case 'H':
			case 'h':
				d = 0b0010111;
				break;
			case 'I':
			case 'i':
				d = 0b0000100;
				break;
			case 'J':
			case 'j':
				d = 0b0111100;
				break;
			case 'K':
			case 'k':
				d = 0b1010111;
				break;
			case 'L':
			case 'l':
				d = 0b0001110;
				break;
			case 'M':
			case 'm':
				d = 0b1110110;
				break;
			case 'N':
			case 'n':
				d = 0b0010101;
				break;
			case 'O':
			case 'o':
				d = 0b0011101;
				break;
			case 'P':
			case 'p':
				d = 0b1100111;
				break;
			case 'Q':
			case 'q':
				d = 0b1101111;
				break;
			case 'R':
			case 'r':
				d = 0b0000101;
				break;
			case 'S':
			case 's':
				d = 0b0011011;
				break;
			case 'T':
			case 't':
				d = 0b0001111;
				break;
			case 'U':
			case 'u':
				d = 0b0011100;
				break;
			case 'V':
			case 'v':
				d = 0b0111110;
				break;
			case 'W':
			case 'w':
				d = 0b0111111;
				break;
			case 'X':
			case 'x':
				d = 0b0110111;
				break;
			case 'Y':
			case 'y':
				d = 0b0111011;
				break;
			case 'Z':
			case 'z':
				d = 0b1101100;
				break;
			default:
				break;
			}
			if(dp) d |= 0x80;
			set(idx, d);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief シフト、バッファ先頭
			@param[in]	fill	埋めるデータ
		 */
		//-----------------------------------------------------------------//
		uint8_t shift_begin(uint8_t fill = 0) {
			uint8_t full = data_[0];
			std::memmove(&data_[1], &data_[0], 7);
			data_[0] = fill;
			return full;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief シフト、バッファ
			@param[in]	fill	埋めるデータ
		 */
		//-----------------------------------------------------------------//
		void shift_last(uint8_t fill = 0) {
			uint8_t full = data_[7];
			std::memmove(&data_[0], &data_[1], 7);
			data_[7] = fill;
			return full;
		}

	};
}
<commit_msg>fix shift API<commit_after>#pragma once
//=====================================================================//
/*!	@file
	@brief	MAX7219 ドライバー
			Copyright 2016 Kunihito Hiramatsu
	@author	平松邦仁 (hira@rvf-rc45.net)
*/
//=====================================================================//
#include <cstdint>
#include <cstring>
#include "common/iica_io.hpp"
#include "common/time.h"

namespace chip {

	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	/*!
		@brief  MAX7219 テンプレートクラス
		@param[in]	SPI		SPI クラス
		@param[in]	SELECT	デバイス選択
		@param[in]	CHAIN	デージー・チェイン数
	*/
	//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
	template <class SPI, class SELECT, uint32_t CHAIN = 1>
	class MAX7219 {

		SPI&		spi_;

		uint16_t	limit_;
		uint8_t		data_[CHAIN * 8];

		enum class command : uint8_t {
			NO_OP        = 0x00,
			DIGIT_0      = 0x01,
			DIGIT_1      = 0x02,
			DIGIT_2      = 0x03,
			DIGIT_3      = 0x04,
			DIGIT_4      = 0x05,
			DIGIT_5      = 0x06,
			DIGIT_6      = 0x07,
			DIGIT_7      = 0x08,
			DECODE_MODE  = 0x09,
			INTENSITY    = 0x0A,
			SCAN_LIMIT   = 0x0B,
			SHUTDOWN     = 0x0C,
			DISPLAY_TEST = 0x0F,
		};

		// MAX7212 MSB first, 2 bytes
		void out_(command cmd, uint8_t dat) {
			SELECT::P = 0;
			uint8_t tmp[2];
			tmp[0] = static_cast<uint8_t>(cmd);
			tmp[1] = dat;
			spi_.send(tmp, 2);
			SELECT::P = 1;  // load
		}

	public:
		//-----------------------------------------------------------------//
		/*!
			@brief	コンストラクター
			@param[in]	spi	SPI クラスを参照で渡す
		 */
		//-----------------------------------------------------------------//
		MAX7219(SPI& spi) : spi_(spi), limit_(0) { }

		//-----------------------------------------------------------------//
		/*!
			@brief	開始
			@param[in]	limit	スキャン・リミット
			@return エラーなら「false」を返す
		 */
		//-----------------------------------------------------------------//
		bool start(uint8_t limit = (CHAIN * 8)) {
			if(limit_ > (8 * CHAIN) || limit == 0) {
				return false;
			}
			limit_ = limit;

			SELECT::DIR = 1;  // output;
			SELECT::PU  = 0;  // pull-up disable
			SELECT::P = 1;    // /CS = H

			for(uint8_t i = 0; i < sizeof(data_); ++i) {
				data_[i] = 0;
			}

			out_(command::SHUTDOWN, 0x01);  // ノーマル・モード
			out_(command::DECODE_MODE, 0x00);  // デコード・モード
			out_(command::SCAN_LIMIT, limit - 1);  // 表示桁設定
			set_intensity(0);  // 輝度（最低）

			service();

			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 輝度の設定
			@param[in]	inten	輝度値（最小：０、最大：１５）
			@return エラー（初期化不良）なら「false」
		 */
		//-----------------------------------------------------------------//
		bool set_intensity(uint8_t inten) {
			if(limit_ == 0) return false;
			out_(command::INTENSITY, inten);
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief データ転送
			@return エラー（初期化不良）なら「false」
		 */
		//-----------------------------------------------------------------//
		bool service() {
			if(limit_ == 0) return false;

			for(uint8_t i = 0; i < limit_; ++i) {
				out_(static_cast<command>(static_cast<uint8_t>(command::DIGIT_0) + i), data_[i]);
			}
			return true;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 値の取得
			@param[in]	idx	インデックス（０～７）
			@return 値
		 */
		//-----------------------------------------------------------------//
		uint8_t get(uint8_t idx) {
			if(idx < limit_) {
				return data_[idx];
			}
			return 0;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief 値の設定
			@param[in]	idx	インデックス（０～７）
			@param[in]	dat	データ
		 */
		//-----------------------------------------------------------------//
		void set(uint8_t idx, uint8_t dat) {
			if(idx < limit_) {
				data_[idx] = dat;
			}
		}

		//-----------------------------------------------------------------//
		/*!
			@brief キャラクターの設定
			@param[in]	idx	インデックス（０～７）
			@param[in]	cha	キャラクターコード
			@param[in]	dp	小数点
		 */
		//-----------------------------------------------------------------//
		void set_cha(uint8_t idx, char cha, bool dp = false) {
			uint8_t d = 0;
			switch(cha) {
			case ' ':
				break;
			case '-':
				d = 0b0000001;
				break;
			case '_':
				d = 0b0001000;
				break;
			case '~':
				d = 0b1000000;
				break;
			case '0':
				d = 0b1111110;
				break;
			case '1':
				d = 0b0110000;
				break;
			case '2':
				d = 0b1101101;
				break;
			case '3':
				d = 0b1111001;
				break;
			case '4':
				d = 0b0110011;
				break;
			case '5':
				d = 0b1011011;
				break;
			case '6':
				d = 0b1011111;
				break;
			case '7':
				d = 0b1110000;
				break;
			case '8':
				d = 0b1111111;
				break;
			case '9':
				d = 0b1111011;
				break;
			case 'A':
			case 'a':
				d = 0b1110111;
				break;
			case 'B':
			case 'b':
				d = 0b0011111;
				break;
			case 'C':
				d = 0b1001110;
				break;
			case 'c':
				d = 0b0001101;
				break;
			case 'D':
			case 'd':
				d = 0b0111101;
				break;
			case 'E':
			case 'e':
				d = 0b1001111;
				break;
			case 'F':
			case 'f':
				d = 0b1000111;
				break;
			case 'G':
			case 'g':
				d = 0b1011110;
				break;
			case 'H':
			case 'h':
				d = 0b0010111;
				break;
			case 'I':
			case 'i':
				d = 0b0000100;
				break;
			case 'J':
			case 'j':
				d = 0b0111100;
				break;
			case 'K':
			case 'k':
				d = 0b1010111;
				break;
			case 'L':
			case 'l':
				d = 0b0001110;
				break;
			case 'M':
			case 'm':
				d = 0b1110110;
				break;
			case 'N':
			case 'n':
				d = 0b0010101;
				break;
			case 'O':
			case 'o':
				d = 0b0011101;
				break;
			case 'P':
			case 'p':
				d = 0b1100111;
				break;
			case 'Q':
			case 'q':
				d = 0b1101111;
				break;
			case 'R':
			case 'r':
				d = 0b0000101;
				break;
			case 'S':
			case 's':
				d = 0b0011011;
				break;
			case 'T':
			case 't':
				d = 0b0001111;
				break;
			case 'U':
			case 'u':
				d = 0b0011100;
				break;
			case 'V':
			case 'v':
				d = 0b0111110;
				break;
			case 'W':
			case 'w':
				d = 0b0111111;
				break;
			case 'X':
			case 'x':
				d = 0b0110111;
				break;
			case 'Y':
			case 'y':
				d = 0b0111011;
				break;
			case 'Z':
			case 'z':
				d = 0b1101100;
				break;
			default:
				break;
			}
			if(dp) d |= 0x80;
			set(idx, d);
		}

		//-----------------------------------------------------------------//
		/*!
			@brief シフト、バッファ先頭
			@param[in]	fill	埋めるデータ
		 */
		//-----------------------------------------------------------------//
		uint8_t shift_top(uint8_t fill = 0) {
			uint8_t full = data_[0];
			std::memmove(&data_[1], &data_[0], 7);
			data_[0] = fill;
			return full;
		}

		//-----------------------------------------------------------------//
		/*!
			@brief シフト、バッファ終端
			@param[in]	fill	埋めるデータ
		 */
		//-----------------------------------------------------------------//
		uint8_t shift_end(uint8_t fill = 0) {
			uint8_t full = data_[7];
			std::memmove(&data_[0], &data_[1], 7);
			data_[7] = fill;
			return full;
		}

	};
}
<|endoftext|>


<commit_before>#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"
#include "overviewpage.h"

#include <QMessageBox>
#include <QPushButton>
#include <QKeyEvent>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);
    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words."));
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
            break;
    }

    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    // Attempt to overwrite text so that they do not linger around in memory
    ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size()));
    ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size()));
    ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size()));
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("Warning: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR COINS!") + "

" + tr("Are you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         "<qt>" +
                                         tr("UltraCoin will close now to finish the encryption process. "
                                         "Remember that encrypting your wallet cannot fully protect "
                                         "your coins from being stolen by malware infecting your computer.") +
                                         "

" +
                                         tr("IMPORTANT: Any previous backups you have made of your wallet file "
                                         "should be replaced with the newly generated, encrypted wallet file. "
                                         "For security reasons, previous backups of the unencrypted wallet file "
                                         "will become useless as soon as you start using the new, encrypted wallet.") +
                                         "</qt>");
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return QDialog::eventFilter(object, event);
}
<commit_msg>Update encrypt message<commit_after>#include "askpassphrasedialog.h"
#include "ui_askpassphrasedialog.h"

#include "guiconstants.h"
#include "walletmodel.h"
#include "overviewpage.h"

#include <QMessageBox>
#include <QPushButton>
#include <QKeyEvent>

AskPassphraseDialog::AskPassphraseDialog(Mode mode, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::AskPassphraseDialog),
    mode(mode),
    model(0),
    fCapsLock(false)
{
    ui->setupUi(this);
    ui->passEdit1->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit2->setMaxLength(MAX_PASSPHRASE_SIZE);
    ui->passEdit3->setMaxLength(MAX_PASSPHRASE_SIZE);

    // Setup Caps Lock detection.
    ui->passEdit1->installEventFilter(this);
    ui->passEdit2->installEventFilter(this);
    ui->passEdit3->installEventFilter(this);

    switch(mode)
    {
        case Encrypt: // Ask passphrase x2
            ui->passLabel1->hide();
            ui->passEdit1->hide();
            ui->warningLabel->setText(tr("Enter the new passphrase to the wallet.
Please use a passphrase of 10 or more random characters, or eight or more words.
 Always encrypt your wallet and save your password or you could lose your coins forever"));
            setWindowTitle(tr("Encrypt wallet"));
            break;
        case Unlock: // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to unlock the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Unlock wallet"));
            break;
        case Decrypt:   // Ask passphrase
            ui->warningLabel->setText(tr("This operation needs your wallet passphrase to decrypt the wallet."));
            ui->passLabel2->hide();
            ui->passEdit2->hide();
            ui->passLabel3->hide();
            ui->passEdit3->hide();
            setWindowTitle(tr("Decrypt wallet"));
            break;
        case ChangePass: // Ask old passphrase + new passphrase x2
            setWindowTitle(tr("Change passphrase"));
            ui->warningLabel->setText(tr("Enter the old and new passphrase to the wallet."));
            break;
    }

    textChanged();
    connect(ui->passEdit1, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit2, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
    connect(ui->passEdit3, SIGNAL(textChanged(QString)), this, SLOT(textChanged()));
}

AskPassphraseDialog::~AskPassphraseDialog()
{
    // Attempt to overwrite text so that they do not linger around in memory
    ui->passEdit1->setText(QString(" ").repeated(ui->passEdit1->text().size()));
    ui->passEdit2->setText(QString(" ").repeated(ui->passEdit2->text().size()));
    ui->passEdit3->setText(QString(" ").repeated(ui->passEdit3->text().size()));
    delete ui;
}

void AskPassphraseDialog::setModel(WalletModel *model)
{
    this->model = model;
}

void AskPassphraseDialog::accept()
{
    SecureString oldpass, newpass1, newpass2;
    if(!model)
        return;
    oldpass.reserve(MAX_PASSPHRASE_SIZE);
    newpass1.reserve(MAX_PASSPHRASE_SIZE);
    newpass2.reserve(MAX_PASSPHRASE_SIZE);
    // TODO: get rid of this .c_str() by implementing SecureString::operator=(std::string)
    // Alternately, find a way to make this input mlock()'d to begin with.
    oldpass.assign(ui->passEdit1->text().toStdString().c_str());
    newpass1.assign(ui->passEdit2->text().toStdString().c_str());
    newpass2.assign(ui->passEdit3->text().toStdString().c_str());

    switch(mode)
    {
    case Encrypt: {
        if(newpass1.empty() || newpass2.empty())
        {
            // Cannot encrypt with empty passphrase
            break;
        }
        QMessageBox::StandardButton retval = QMessageBox::question(this, tr("Confirm wallet encryption"),
                 tr("Warning: If you encrypt your wallet and lose your passphrase, you will LOSE ALL OF YOUR COINS!") + "

" + tr("Are you sure you wish to encrypt your wallet?"),
                 QMessageBox::Yes|QMessageBox::Cancel,
                 QMessageBox::Cancel);
        if(retval == QMessageBox::Yes)
        {
            if(newpass1 == newpass2)
            {
                if(model->setWalletEncrypted(true, newpass1))
                {
                    QMessageBox::warning(this, tr("Wallet encrypted"),
                                         "<qt>" +
                                         tr("UltraCoin will close now to finish the encryption process. "
                                         "Remember that encrypting your wallet cannot fully protect "
                                         "your coins from being stolen by malware infecting your computer.") +
                                         "

" +
                                         tr("IMPORTANT: Any previous backups you have made of your wallet file "
                                         "should be replaced with the newly generated, encrypted wallet file. "
                                         "For security reasons, previous backups of the unencrypted wallet file "
                                         "will become useless as soon as you start using the new, encrypted wallet.") +
                                         "</qt>");
                    QApplication::quit();
                }
                else
                {
                    QMessageBox::critical(this, tr("Wallet encryption failed"),
                                         tr("Wallet encryption failed due to an internal error. Your wallet was not encrypted."));
                }
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The supplied passphrases do not match."));
            }
        }
        else
        {
            QDialog::reject(); // Cancelled
        }
        } break;
    case Unlock:
        if(!model->setWalletLocked(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet unlock failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case Decrypt:
        if(!model->setWalletEncrypted(false, oldpass))
        {
            QMessageBox::critical(this, tr("Wallet decryption failed"),
                                  tr("The passphrase entered for the wallet decryption was incorrect."));
        }
        else
        {
            QDialog::accept(); // Success
        }
        break;
    case ChangePass:
        if(newpass1 == newpass2)
        {
            if(model->changePassphrase(oldpass, newpass1))
            {
                QMessageBox::information(this, tr("Wallet encrypted"),
                                     tr("Wallet passphrase was successfully changed."));
                QDialog::accept(); // Success
            }
            else
            {
                QMessageBox::critical(this, tr("Wallet encryption failed"),
                                     tr("The passphrase entered for the wallet decryption was incorrect."));
            }
        }
        else
        {
            QMessageBox::critical(this, tr("Wallet encryption failed"),
                                 tr("The supplied passphrases do not match."));
        }
        break;
    }
}

void AskPassphraseDialog::textChanged()
{
    // Validate input, set Ok button to enabled when acceptable
    bool acceptable = false;
    switch(mode)
    {
    case Encrypt: // New passphrase x2
        acceptable = !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    case Unlock: // Old passphrase x1
    case Decrypt:
        acceptable = !ui->passEdit1->text().isEmpty();
        break;
    case ChangePass: // Old passphrase x1, new passphrase x2
        acceptable = !ui->passEdit1->text().isEmpty() && !ui->passEdit2->text().isEmpty() && !ui->passEdit3->text().isEmpty();
        break;
    }
    ui->buttonBox->button(QDialogButtonBox::Ok)->setEnabled(acceptable);
}

bool AskPassphraseDialog::event(QEvent *event)
{
    // Detect Caps Lock key press.
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        if (ke->key() == Qt::Key_CapsLock) {
            fCapsLock = !fCapsLock;
        }
        if (fCapsLock) {
            ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
        } else {
            ui->capsLabel->clear();
        }
    }
    return QWidget::event(event);
}

bool AskPassphraseDialog::eventFilter(QObject *object, QEvent *event)
{
    /* Detect Caps Lock.
     * There is no good OS-independent way to check a key state in Qt, but we
     * can detect Caps Lock by checking for the following condition:
     * Shift key is down and the result is a lower case character, or
     * Shift key is not down and the result is an upper case character.
     */
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = static_cast<QKeyEvent *>(event);
        QString str = ke->text();
        if (str.length() != 0) {
            const QChar *psz = str.unicode();
            bool fShift = (ke->modifiers() & Qt::ShiftModifier) != 0;
            if ((fShift && psz->isLower()) || (!fShift && psz->isUpper())) {
                fCapsLock = true;
                ui->capsLabel->setText(tr("Warning: The Caps Lock key is on!"));
            } else if (psz->isLetter()) {
                fCapsLock = false;
                ui->capsLabel->clear();
            }
        }
    }
    return QDialog::eventFilter(object, event);
}
<|endoftext|>