<commit_before>/*
 * Copyright (C) 2011
 * Alessio Sclocco <a.sclocco@vu.nl>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <string>
#include <utility>

using std::string;
using std::make_pair;

#include <kernels/Kernel.hpp>
#include <GPUData.hpp>
#include <Exceptions.hpp>
#include <utils.hpp>

using isa::OpenCL::Kernel;
using isa::OpenCL::GPUData;
using isa::Exceptions::OpenCLError;
using isa::utils::toStringValue;

#ifndef MEMSET_HPP
#define MEMSET_HPP

namespace isa {

namespace OpenCL {

template < typename T > class Memset : public Kernel< T > {
public:
	Memset(string dataType);

	void generateCode() throw (OpenCLError);
	void operator()(T value, GPUData< T > *memory) throw (OpenCLError);

	inline void setNrThreadsPerBlock(unsigned int threads);
	inline void setNrThreads(unsigned int threads);
	inline void setNrRows(unsigned int rows);

private:
	string *code;
	unsigned int nrThreadsPerBlock;
	unsigned int nrThreads;
	unsigned int nrRows;
};

// Implementation

template< typename T > Memset< T >::Memset(string dataType) : Kernel< T >("Memset", dataType), code(0), nrThreadsPerBlock(0), nrThreads(0), nrRows(0) {}

template< typename T > void Memset< T >::generateCode() throw (OpenCLError) {
	if ( this->code != 0 ) {
		delete this->code;
	}
	this->code = new string();
	*(this->code) = "__kernel void " + this->name + "(" + this->dataType + " value, __global " + this->dataType + " *mem) {\n"
		"unsigned int id = (get_group_id(1) * get_num_groups(0) * get_local_size(0)) + (get_group_id(0) * get_local_size(0)) + get_local_id(0);\n"
		"mem[id] = value;\n"
		"}";

	this->setAsync(true);
	this->compile();
}

template< typename T > void Memset< T >::operator()(T value, GPUData< T > *memory) throw (OpenCLError) {
	cl::NDRange globalSize(nrThreads / nrRows, nrRows);
	cl::NDRange localSize(nrThreadsPerBlock, 1);

	this->setArgument(0, value);
	this->setArgument(1, *(memory->getDeviceData()));

	this->run(globalSize, localSize);
}

template< typename T > inline void Memset< T >::setNrThreadsPerBlock(unsigned int threads) {
	nrThreadsPerBlock = threads;
}

template< typename T > inline void Memset< T >::setNrThreads(unsigned int threads) {
	nrThreads = threads;
}

template< typename T > inline void Memset< T >::setNrRows(unsigned int rows) {
	nrRows = rows;
}

} // OpenCL
} // isa

#endif // MEMSET_HPP

<commit_msg>A small bug in Memset. Solved now.<commit_after>/*
 * Copyright (C) 2011
 * Alessio Sclocco <a.sclocco@vu.nl>
 *
 * 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.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <string>
#include <utility>

using std::string;
using std::make_pair;

#include <kernels/Kernel.hpp>
#include <GPUData.hpp>
#include <Exceptions.hpp>
#include <utils.hpp>

using isa::OpenCL::Kernel;
using isa::OpenCL::GPUData;
using isa::Exceptions::OpenCLError;
using isa::utils::toStringValue;

#ifndef MEMSET_HPP
#define MEMSET_HPP

namespace isa {

namespace OpenCL {

template < typename T > class Memset : public Kernel< T > {
public:
	Memset(string dataType);

	void generateCode() throw (OpenCLError);
	void operator()(T value, GPUData< T > *memory) throw (OpenCLError);

	inline void setNrThreadsPerBlock(unsigned int threads);
	inline void setNrThreads(unsigned int threads);
	inline void setNrRows(unsigned int rows);

private:
	unsigned int nrThreadsPerBlock;
	unsigned int nrThreads;
	unsigned int nrRows;
};

// Implementation

template< typename T > Memset< T >::Memset(string dataType) : Kernel< T >("Memset", dataType), nrThreadsPerBlock(0), nrThreads(0), nrRows(0) {}

template< typename T > void Memset< T >::generateCode() throw (OpenCLError) {
	if ( this->code != 0 ) {
		delete this->code;
	}
	this->code = new string();
	*(this->code) = "__kernel void " + this->name + "(" + this->dataType + " value, __global " + this->dataType + " *mem) {\n"
		"unsigned int id = (get_group_id(1) * get_num_groups(0) * get_local_size(0)) + (get_group_id(0) * get_local_size(0)) + get_local_id(0);\n"
		"mem[id] = value;\n"
		"}";

	this->setAsync(true);
	this->compile();
}

template< typename T > void Memset< T >::operator()(T value, GPUData< T > *memory) throw (OpenCLError) {
	cl::NDRange globalSize(nrThreads / nrRows, nrRows);
	cl::NDRange localSize(nrThreadsPerBlock, 1);

	this->setArgument(0, value);
	this->setArgument(1, *(memory->getDeviceData()));

	this->run(globalSize, localSize);
}

template< typename T > inline void Memset< T >::setNrThreadsPerBlock(unsigned int threads) {
	nrThreadsPerBlock = threads;
}

template< typename T > inline void Memset< T >::setNrThreads(unsigned int threads) {
	nrThreads = threads;
}

template< typename T > inline void Memset< T >::setNrRows(unsigned int rows) {
	nrRows = rows;
}

} // OpenCL
} // isa

#endif // MEMSET_HPP

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef WEBSOCKET_CONSTANTS_HPP
#define WEBSOCKET_CONSTANTS_HPP

#ifndef __STDC_LIMIT_MACROS
  #define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>

// SIZE_MAX appears to be a compiler thing not an OS header thing.
// make sure it is defined.
#ifndef SIZE_MAX
    #define SIZE_MAX ((size_t)(-1))
#endif

#ifdef _MSC_VER
    #ifndef _WEBSOCKETPP_CPP11_FRIEND_
        #define _WEBSOCKETPP_CPP11_FRIEND_
    #endif
#endif

#include <exception>
#include <string>
#include <vector>

#include <boost/shared_ptr.hpp>

// Defaults
namespace websocketpp {
    static const std::string USER_AGENT = "WebSocket++/0.2.0dev";

    typedef std::vector<unsigned char> binary_string;
    typedef boost::shared_ptr<binary_string> binary_string_ptr;

    typedef std::string utf8_string;
    typedef boost::shared_ptr<utf8_string> utf8_string_ptr;

    const uint64_t DEFAULT_MAX_MESSAGE_SIZE = 0xFFFFFF; // ~16MB

    const size_t DEFAULT_READ_THRESHOLD = 1; // 512 would be a more sane value for this
    const bool DEFAULT_SILENT_CLOSE = false; // true

    const size_t MAX_THREAD_POOL_SIZE = 64;

    const uint16_t DEFAULT_PORT = 80;
    const uint16_t DEFAULT_SECURE_PORT = 443;

    inline uint16_t default_port(bool secure) {
        return (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT);
    }

    namespace session {
        namespace state {
            enum value {
                CONNECTING = 0,
                OPEN = 1,
                CLOSING = 2,
                CLOSED = 3
            };
        }
    }

    namespace close {
    namespace status {
        enum value {
            INVALID_END = 999,
            NORMAL = 1000,
            GOING_AWAY = 1001,
            PROTOCOL_ERROR = 1002,
            UNSUPPORTED_DATA = 1003,
            RSV_ADHOC_1 = 1004,
            NO_STATUS = 1005,
            ABNORMAL_CLOSE = 1006,
            INVALID_PAYLOAD = 1007,
            POLICY_VIOLATION = 1008,
            MESSAGE_TOO_BIG = 1009,
            EXTENSION_REQUIRE = 1010,
            INTERNAL_ENDPOINT_ERROR = 1011,
            RSV_ADHOC_2 = 1012,
            RSV_ADHOC_3 = 1013,
            RSV_ADHOC_4 = 1014,
            TLS_HANDSHAKE = 1015,
            RSV_START = 1016,
            RSV_END = 2999,
            INVALID_START = 5000
        };

        inline bool reserved(value s) {
            return ((s >= RSV_START && s <= RSV_END) || s == RSV_ADHOC_1
                    || s == RSV_ADHOC_2 || s == RSV_ADHOC_3 || s == RSV_ADHOC_4);
        }

        // Codes invalid on the wire
        inline bool invalid(value s) {
            return ((s <= INVALID_END || s >= INVALID_START) ||
                    s == NO_STATUS ||
                    s == ABNORMAL_CLOSE ||
                    s == TLS_HANDSHAKE);
        }

        // TODO functions for application ranges?
    } // namespace status
    } // namespace close

    namespace fail {
    namespace status {
        enum value {
            GOOD = 0,           // no failure yet!
            SYSTEM = 1,         // system call returned error, check that code
            WEBSOCKET = 2,      // websocket close codes contain error
            UNKNOWN = 3,        // No failure information is avaliable
            TIMEOUT_TLS = 4,    // TLS handshake timed out
            TIMEOUT_WS = 5      // WS handshake timed out
        };
    } // namespace status
    } // namespace fail

    namespace frame {
        // Opcodes are 4 bits
        // See spec section 5.2
        namespace opcode {
            enum value {
                CONTINUATION = 0x0,
                TEXT = 0x1,
                BINARY = 0x2,
                RSV3 = 0x3,
                RSV4 = 0x4,
                RSV5 = 0x5,
                RSV6 = 0x6,
                RSV7 = 0x7,
                CLOSE = 0x8,
                PING = 0x9,
                PONG = 0xA,
                CONTROL_RSVB = 0xB,
                CONTROL_RSVC = 0xC,
                CONTROL_RSVD = 0xD,
                CONTROL_RSVE = 0xE,
                CONTROL_RSVF = 0xF
            };

            inline bool reserved(value v) {
                return (v >= RSV3 && v <= RSV7) ||
                (v >= CONTROL_RSVB && v <= CONTROL_RSVF);
            }

            inline bool invalid(value v) {
                return (v > 0xF || v < 0);
            }

            inline bool is_control(value v) {
                return v >= 0x8;
            }
        }

        namespace limits {
            static const uint8_t PAYLOAD_SIZE_BASIC = 125;
            static const uint16_t PAYLOAD_SIZE_EXTENDED = 0xFFFF; // 2^16, 65535
            static const uint64_t PAYLOAD_SIZE_JUMBO = 0x7FFFFFFFFFFFFFFFLL;//2^63
        }
    } // namespace frame

    // exception class for errors that should be propogated back to the user.
    namespace error {
        enum value {
            GENERIC = 0,
            // send attempted when endpoint write queue was full
            SEND_QUEUE_FULL = 1,
            PAYLOAD_VIOLATION = 2,
            ENDPOINT_UNSECURE = 3,
            ENDPOINT_UNAVAILABLE = 4,
            INVALID_URI = 5,
            NO_OUTGOING_MESSAGES = 6,
            INVALID_STATE = 7
        };
    }

    class exception : public std::exception {
    public:
        exception(const std::string& msg,
                  error::value code = error::GENERIC)
        : m_msg(msg),m_code(code) {}
        ~exception() throw() {}

        virtual const char* what() const throw() {
            return m_msg.c_str();
        }

        error::value code() const throw() {
            return m_code;
        }

        std::string m_msg;
        error::value m_code;
    };
}

#endif // WEBSOCKET_CONSTANTS_HPP
<commit_msg>Updates user agent/version string<commit_after>/*
 * Copyright (c) 2011, Peter Thorson. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the WebSocket++ Project nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL PETER THORSON BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef WEBSOCKET_CONSTANTS_HPP
#define WEBSOCKET_CONSTANTS_HPP

#ifndef __STDC_LIMIT_MACROS
  #define __STDC_LIMIT_MACROS
#endif
#include <stdint.h>

// SIZE_MAX appears to be a compiler thing not an OS header thing.
// make sure it is defined.
#ifndef SIZE_MAX
    #define SIZE_MAX ((size_t)(-1))
#endif

#ifdef _MSC_VER
    #ifndef _WEBSOCKETPP_CPP11_FRIEND_
        #define _WEBSOCKETPP_CPP11_FRIEND_
    #endif
#endif

#include <exception>
#include <string>
#include <vector>

#include <boost/shared_ptr.hpp>

// Defaults
namespace websocketpp {
    static const std::string USER_AGENT = "WebSocket++/0.2.1dev";

    typedef std::vector<unsigned char> binary_string;
    typedef boost::shared_ptr<binary_string> binary_string_ptr;

    typedef std::string utf8_string;
    typedef boost::shared_ptr<utf8_string> utf8_string_ptr;

    const uint64_t DEFAULT_MAX_MESSAGE_SIZE = 0xFFFFFF; // ~16MB

    const size_t DEFAULT_READ_THRESHOLD = 1; // 512 would be a more sane value for this
    const bool DEFAULT_SILENT_CLOSE = false; // true

    const size_t MAX_THREAD_POOL_SIZE = 64;

    const uint16_t DEFAULT_PORT = 80;
    const uint16_t DEFAULT_SECURE_PORT = 443;

    inline uint16_t default_port(bool secure) {
        return (secure ? DEFAULT_SECURE_PORT : DEFAULT_PORT);
    }

    namespace session {
        namespace state {
            enum value {
                CONNECTING = 0,
                OPEN = 1,
                CLOSING = 2,
                CLOSED = 3
            };
        }
    }

    namespace close {
    namespace status {
        enum value {
            INVALID_END = 999,
            NORMAL = 1000,
            GOING_AWAY = 1001,
            PROTOCOL_ERROR = 1002,
            UNSUPPORTED_DATA = 1003,
            RSV_ADHOC_1 = 1004,
            NO_STATUS = 1005,
            ABNORMAL_CLOSE = 1006,
            INVALID_PAYLOAD = 1007,
            POLICY_VIOLATION = 1008,
            MESSAGE_TOO_BIG = 1009,
            EXTENSION_REQUIRE = 1010,
            INTERNAL_ENDPOINT_ERROR = 1011,
            RSV_ADHOC_2 = 1012,
            RSV_ADHOC_3 = 1013,
            RSV_ADHOC_4 = 1014,
            TLS_HANDSHAKE = 1015,
            RSV_START = 1016,
            RSV_END = 2999,
            INVALID_START = 5000
        };

        inline bool reserved(value s) {
            return ((s >= RSV_START && s <= RSV_END) || s == RSV_ADHOC_1
                    || s == RSV_ADHOC_2 || s == RSV_ADHOC_3 || s == RSV_ADHOC_4);
        }

        // Codes invalid on the wire
        inline bool invalid(value s) {
            return ((s <= INVALID_END || s >= INVALID_START) ||
                    s == NO_STATUS ||
                    s == ABNORMAL_CLOSE ||
                    s == TLS_HANDSHAKE);
        }

        // TODO functions for application ranges?
    } // namespace status
    } // namespace close

    namespace fail {
    namespace status {
        enum value {
            GOOD = 0,           // no failure yet!
            SYSTEM = 1,         // system call returned error, check that code
            WEBSOCKET = 2,      // websocket close codes contain error
            UNKNOWN = 3,        // No failure information is avaliable
            TIMEOUT_TLS = 4,    // TLS handshake timed out
            TIMEOUT_WS = 5      // WS handshake timed out
        };
    } // namespace status
    } // namespace fail

    namespace frame {
        // Opcodes are 4 bits
        // See spec section 5.2
        namespace opcode {
            enum value {
                CONTINUATION = 0x0,
                TEXT = 0x1,
                BINARY = 0x2,
                RSV3 = 0x3,
                RSV4 = 0x4,
                RSV5 = 0x5,
                RSV6 = 0x6,
                RSV7 = 0x7,
                CLOSE = 0x8,
                PING = 0x9,
                PONG = 0xA,
                CONTROL_RSVB = 0xB,
                CONTROL_RSVC = 0xC,
                CONTROL_RSVD = 0xD,
                CONTROL_RSVE = 0xE,
                CONTROL_RSVF = 0xF
            };

            inline bool reserved(value v) {
                return (v >= RSV3 && v <= RSV7) ||
                (v >= CONTROL_RSVB && v <= CONTROL_RSVF);
            }

            inline bool invalid(value v) {
                return (v > 0xF || v < 0);
            }

            inline bool is_control(value v) {
                return v >= 0x8;
            }
        }

        namespace limits {
            static const uint8_t PAYLOAD_SIZE_BASIC = 125;
            static const uint16_t PAYLOAD_SIZE_EXTENDED = 0xFFFF; // 2^16, 65535
            static const uint64_t PAYLOAD_SIZE_JUMBO = 0x7FFFFFFFFFFFFFFFLL;//2^63
        }
    } // namespace frame

    // exception class for errors that should be propogated back to the user.
    namespace error {
        enum value {
            GENERIC = 0,
            // send attempted when endpoint write queue was full
            SEND_QUEUE_FULL = 1,
            PAYLOAD_VIOLATION = 2,
            ENDPOINT_UNSECURE = 3,
            ENDPOINT_UNAVAILABLE = 4,
            INVALID_URI = 5,
            NO_OUTGOING_MESSAGES = 6,
            INVALID_STATE = 7
        };
    }

    class exception : public std::exception {
    public:
        exception(const std::string& msg,
                  error::value code = error::GENERIC)
        : m_msg(msg),m_code(code) {}
        ~exception() throw() {}

        virtual const char* what() const throw() {
            return m_msg.c_str();
        }

        error::value code() const throw() {
            return m_code;
        }

        std::string m_msg;
        error::value m_code;
    };
}

#endif // WEBSOCKET_CONSTANTS_HPP
<|endoftext|>


<commit_before>// UjoImro, 2013
// Experimental code for the CARP Project
// Copyright (c) RealEyes, 2013
// This version tests the responseMap calculation with input dumps

#include <chrono>
#include <string>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <boost/preprocessor.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include "cast.h"
#include "mlp.hpp"
#include "mlp_impl.h"

/*
extern int EF_ALIGNMENT = 0;
extern int EF_PROTECT_BELOW = 0;
extern int EF_PROTECT_FREE = 0;
extern int EF_ALLOW_MALLOC_0 = 1;
extern int EF_FILL = 1922;
*/

namespace { struct hack_t; }
MatChar  convertCVToMatChar ( const cv::Mat_<uint8_t> & input );
mlp *    convertHackToMlp ( const hack_t & hack );
void     freeClassifiers( mlp * classifiers[], int size );
MatChar  convertCVToMatChar ( const cv::Mat_<uint8_t> & input );
MatFloat convertCVToMatFloat (  const cv::Mat_<double> & input );
cv::Mat_<double> convertMatFloatToCV( MatFloat input );
void     allocateResponseMaps( int mapSize, int size, MatFloat * responseMaps[] );
void     freeResponseMaps( MatFloat * responseMaps[], int size );

namespace {

    struct hack_t {
        int m_visibleLandmarks_size;
        int m_mapSize;

        cv::Mat_<double> shape;
        cv::Mat_<uint8_t> alignedImage;
        std::vector<gel::MLP<double> > m_classifiers;
        std::vector<cv::Mat_<double> > responseMaps;

        template <class MT0>
        void serialize( MT0 & archiver, unsigned int ) {
            GEL_EXPORT_VAR( archiver, m_visibleLandmarks_size );
            GEL_EXPORT_VAR( archiver, m_mapSize );
            GEL_EXPORT_VAR( archiver, shape );
            GEL_EXPORT_VAR( archiver, alignedImage );
            GEL_EXPORT_VAR( archiver, m_classifiers );
            GEL_EXPORT_VAR( archiver, responseMaps );
        } // serialize

    }; // struct hack_t

    class conductor_t {
    public:
        int id;
        hack_t hack;
        std::ifstream dumpStream;
        boost::archive::binary_iarchive importer;

    public:

        conductor_t() : id(0), dumpStream("response_dumps.bin", std::ios::in | std::ios::binary ), importer(dumpStream) {

        }; // conductor_t

    }; // conductor_t

} // unnamed namespace

mlp *
convertHackToMlp ( const hack_t & hack )
{
    assert(hack.m_visibleLandmarks_size==hack.m_classifiers.size());
    assert(hack.m_visibleLandmarks_size==hack.responseMaps.size());

    mlp * result;
    result = reinterpret_cast<mlp*>( malloc( sizeof(mlp) * hack.m_visibleLandmarks_size ) );

    // we export each classifier
    for (int q=0; q<hack.m_visibleLandmarks_size; q++)
    {
        result[q].m_patchSize = hack.m_classifiers[q].m_patchSize;
        result[q].m_wIn       = convertCVToMatFloat(hack.m_classifiers[q].m_wIn);
        result[q].m_wOut      = convertCVToMatFloat(hack.m_classifiers[q].m_wOut);
        result[q].m_U         = convertCVToMatFloat(hack.m_classifiers[q].m_U);
        result[q].hidden_num  = hack.m_classifiers[q].hidden_num;
        result[q].rho2        = hack.m_classifiers[q].rho2;
    } // for q in m_visibleLandmarks_size

    return result;
} // convertHackToMlp

void
freeClassifiers( mlp * classifiers[], int size )
{
    mlp * result = *classifiers;
    for (int q=0; q<size; q++ )
        freeMLP( &(result[q]) );

    free(*classifiers);
    *classifiers=NULL;

    return;
} // freeClassifiers

MatChar convertCVToMatChar ( const cv::Mat_<uint8_t> & input )
{
    MatChar result = CreateMatChar( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result.data[ q * result.step + w + result.start ] = input(q,w);

    return result;
} // convertCVToMatChar

MatFloat convertCVToMatFloat (  const cv::Mat_<double> & input )
{
    MatFloat result = CreateMatFloat( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result.data[ q * result.step + w + result.start ] = input(q,w);

    return result;
} // convertCVToMatFloat

cv::Mat_<double> convertMatFloatToCV( MatFloat input )
{
    cv::Mat_<double> result( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result(q,w) = input.data[ q * input.step + w + input.start ];

    return result;
} // convertMatFloatToCV

void allocateResponseMaps( int mapSize, int size, MatFloat * responseMaps[] )
{
    *responseMaps = (MatFloat*)malloc( sizeof(MatFloat) * size );
    assert(*responseMaps);
    MatFloat * result = *responseMaps;

    for ( int q=0; q<size; q++ )
        result[q] = CreateMatFloat( 2 * mapSize + 1, 2 * mapSize + 1 );

    return;
}

void freeResponseMaps( MatFloat * responseMaps[], int size )
{
    MatFloat * result = *responseMaps;
    assert(result);
    for ( int q=0; q<size; q++ )
        freeMatFloat(&(result[q]));

    free(result);
    *responseMaps=NULL;
    return;
}

template <class T0>
auto
microseconds( T0 t0 ) -> decltype(std::chrono::duration_cast<std::chrono::microseconds>(t0).count())
{
    return std::chrono::duration_cast<std::chrono::microseconds>(t0).count();
}

int main()
{
    conductor_t conductor;
    int fail = 0;
    long int elapsed_time = 0;

    for ( conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.id);
          ((conductor.id != -1) and (conductor.id != 25));
          // conductor.id != -1;
          conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.id)
        )
    {
        PRINT(conductor.id);
        conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.hack);

        // here comes the function call
        {
            // preparing the inputs
            MatChar alignedImage = convertCVToMatChar(conductor.hack.alignedImage);
            MatFloat shape = convertCVToMatFloat(conductor.hack.shape);
            mlp * m_classifiers = convertHackToMlp(conductor.hack);
            MatFloat * responseMaps;
            allocateResponseMaps( conductor.hack.m_mapSize, conductor.hack.m_visibleLandmarks_size, &responseMaps );

            auto start = std::chrono::high_resolution_clock::now();
            calculateMaps(
                conductor.hack.m_visibleLandmarks_size,
                conductor.hack.m_mapSize,
                alignedImage,
                shape,
                m_classifiers,
                &responseMaps
                );
            auto end = std::chrono::high_resolution_clock::now();
            elapsed_time = microseconds(end - start);

            // releasing the inputs
            freeMatChar(&alignedImage);
            freeMatFloat(&shape);
            freeClassifiers(&m_classifiers, conductor.hack.m_classifiers.size());

            // converting the outputs
            std::vector< cv::Mat_<double> > calculatedResults;
            for (int q=0; q<conductor.hack.m_visibleLandmarks_size; q++)
            {
                cv::Mat_<double> nextResult;
                nextResult = convertMatFloatToCV( responseMaps[q] );
                calculatedResults.push_back(nextResult);
            }

            // testing the output
            for (int q=0; q<conductor.hack.m_visibleLandmarks_size; q++)
            {
                // std::cout << "cv::norm( conductor.hack.responseMaps[" << q << "] - calculatedResults[" << q << "] ) = "
                //           << cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) << std::endl;
                assert(cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) < 1.5);
                if (cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) > 0.5 ) fail++;
                // PRINT(fail);
                int tolerance = 49 * conductor.id * 0.005 + 3;
                // PRINT(tolerance);
                assert(fail < tolerance);
            }

            // releasing the outputs
            freeResponseMaps( &responseMaps, conductor.hack.m_visibleLandmarks_size );

        }
        // here comes the test
        // PRINT(cv::norm( ));
    }

    std::cout << "total elapsed time = " << elapsed_time / 1000000. << " s." << std::endl;
    //conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.hack);

    return EXIT_SUCCESS;
}

// LuM end of file
<commit_msg>testing the precision by outliers in test_mlp<commit_after>// UjoImro, 2013
// Experimental code for the CARP Project
// Copyright (c) RealEyes, 2013
// This version tests the responseMap calculation with input dumps

#include <chrono>
#include <string>
#include <stdlib.h>
#include <opencv2/core/core.hpp>
#include <boost/preprocessor.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/archive/binary_iarchive.hpp>

#include "cast.h"
#include "mlp.hpp"
#include "mlp_impl.h"

/*
extern int EF_ALIGNMENT = 0;
extern int EF_PROTECT_BELOW = 0;
extern int EF_PROTECT_FREE = 0;
extern int EF_ALLOW_MALLOC_0 = 1;
extern int EF_FILL = 1922;
*/

namespace { struct hack_t; }
MatChar  convertCVToMatChar ( const cv::Mat_<uint8_t> & input );
mlp *    convertHackToMlp ( const hack_t & hack );
void     freeClassifiers( mlp * classifiers[], int size );
MatChar  convertCVToMatChar ( const cv::Mat_<uint8_t> & input );
MatFloat convertCVToMatFloat (  const cv::Mat_<double> & input );
cv::Mat_<double> convertMatFloatToCV( MatFloat input );
void     allocateResponseMaps( int mapSize, int size, MatFloat * responseMaps[] );
void     freeResponseMaps( MatFloat * responseMaps[], int size );

namespace {

    struct hack_t {
        int m_visibleLandmarks_size;
        int m_mapSize;

        cv::Mat_<double> shape;
        cv::Mat_<uint8_t> alignedImage;
        std::vector<gel::MLP<double> > m_classifiers;
        std::vector<cv::Mat_<double> > responseMaps;

        template <class MT0>
        void serialize( MT0 & archiver, unsigned int ) {
            GEL_EXPORT_VAR( archiver, m_visibleLandmarks_size );
            GEL_EXPORT_VAR( archiver, m_mapSize );
            GEL_EXPORT_VAR( archiver, shape );
            GEL_EXPORT_VAR( archiver, alignedImage );
            GEL_EXPORT_VAR( archiver, m_classifiers );
            GEL_EXPORT_VAR( archiver, responseMaps );
        } // serialize

    }; // struct hack_t

    class conductor_t {
    public:
        int id;
        hack_t hack;
        std::ifstream dumpStream;
        boost::archive::binary_iarchive importer;

    public:

        conductor_t() : id(0), dumpStream("response_dumps.bin", std::ios::in | std::ios::binary ), importer(dumpStream) {

        }; // conductor_t

    }; // conductor_t

} // unnamed namespace

mlp *
convertHackToMlp ( const hack_t & hack )
{
    assert(hack.m_visibleLandmarks_size==hack.m_classifiers.size());
    assert(hack.m_visibleLandmarks_size==hack.responseMaps.size());

    mlp * result;
    result = reinterpret_cast<mlp*>( malloc( sizeof(mlp) * hack.m_visibleLandmarks_size ) );

    // we export each classifier
    for (int q=0; q<hack.m_visibleLandmarks_size; q++)
    {
        result[q].m_patchSize = hack.m_classifiers[q].m_patchSize;
        result[q].m_wIn       = convertCVToMatFloat(hack.m_classifiers[q].m_wIn);
        result[q].m_wOut      = convertCVToMatFloat(hack.m_classifiers[q].m_wOut);
        result[q].m_U         = convertCVToMatFloat(hack.m_classifiers[q].m_U);
        result[q].hidden_num  = hack.m_classifiers[q].hidden_num;
        result[q].rho2        = hack.m_classifiers[q].rho2;
    } // for q in m_visibleLandmarks_size

    return result;
} // convertHackToMlp

void
freeClassifiers( mlp * classifiers[], int size )
{
    mlp * result = *classifiers;
    for (int q=0; q<size; q++ )
        freeMLP( &(result[q]) );

    free(*classifiers);
    *classifiers=NULL;

    return;
} // freeClassifiers

MatChar convertCVToMatChar ( const cv::Mat_<uint8_t> & input )
{
    MatChar result = CreateMatChar( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result.data[ q * result.step + w + result.start ] = input(q,w);

    return result;
} // convertCVToMatChar

MatFloat convertCVToMatFloat (  const cv::Mat_<double> & input )
{
    MatFloat result = CreateMatFloat( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result.data[ q * result.step + w + result.start ] = input(q,w);

    return result;
} // convertCVToMatFloat

cv::Mat_<double> convertMatFloatToCV( MatFloat input )
{
    cv::Mat_<double> result( input.rows, input.cols );

    for ( int q=0; q<input.rows; q++)
        for ( int w=0; w<input.cols; w++ )
            result(q,w) = input.data[ q * input.step + w + input.start ];

    return result;
} // convertMatFloatToCV

void allocateResponseMaps( int mapSize, int size, MatFloat * responseMaps[] )
{
    *responseMaps = (MatFloat*)malloc( sizeof(MatFloat) * size );
    assert(*responseMaps);
    MatFloat * result = *responseMaps;

    for ( int q=0; q<size; q++ )
        result[q] = CreateMatFloat( 2 * mapSize + 1, 2 * mapSize + 1 );

    return;
}

void freeResponseMaps( MatFloat * responseMaps[], int size )
{
    MatFloat * result = *responseMaps;
    assert(result);
    for ( int q=0; q<size; q++ )
        freeMatFloat(&(result[q]));

    free(result);
    *responseMaps=NULL;
    return;
}

template <class T0>
auto
microseconds( T0 t0 ) -> decltype(std::chrono::duration_cast<std::chrono::microseconds>(t0).count())
{
    return std::chrono::duration_cast<std::chrono::microseconds>(t0).count();
}

int main()
{
    conductor_t conductor;
    int fail = 0;
    long int elapsed_time = 0;

    for ( conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.id);
          ((conductor.id != -1) and (conductor.id != 25));
          // conductor.id != -1;
          conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.id)
        )
    {
        PRINT(conductor.id);
        conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.hack);

        // here comes the function call
        {
            // preparing the inputs
            MatChar alignedImage = convertCVToMatChar(conductor.hack.alignedImage);
            MatFloat shape = convertCVToMatFloat(conductor.hack.shape);
            mlp * m_classifiers = convertHackToMlp(conductor.hack);
            MatFloat * responseMaps;
            allocateResponseMaps( conductor.hack.m_mapSize, conductor.hack.m_visibleLandmarks_size, &responseMaps );

            auto start = std::chrono::high_resolution_clock::now();
            calculateMaps(
                conductor.hack.m_visibleLandmarks_size,
                conductor.hack.m_mapSize,
                alignedImage,
                shape,
                m_classifiers,
                &responseMaps
                );
            auto end = std::chrono::high_resolution_clock::now();
            elapsed_time = microseconds(end - start);

            // releasing the inputs
            freeMatChar(&alignedImage);
            freeMatFloat(&shape);
            freeClassifiers(&m_classifiers, conductor.hack.m_classifiers.size());

            // converting the outputs
            std::vector< cv::Mat_<double> > calculatedResults;
            for (int q=0; q<conductor.hack.m_visibleLandmarks_size; q++)
            {
                cv::Mat_<double> nextResult;
                nextResult = convertMatFloatToCV( responseMaps[q] );
                calculatedResults.push_back(nextResult);
            }

            // testing the output
            for (int q=0; q<conductor.hack.m_visibleLandmarks_size; q++)
            {
              // std::cout << "cv::norm( conductor.hack.responseMaps[" << q << "] - calculatedResults[" << q << "] ) = "
              //           << cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) << std::endl;
                assert(cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) < 1.5);
                if (cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) > 0.5 )
                {
                  fail++;
                  std::cout << "cv::norm( conductor.hack.responseMaps[" << q << "] - calculatedResults[" << q << "] ) = "
                            << cv::norm( conductor.hack.responseMaps[q] - calculatedResults[q] ) << std::endl;

                }

                // PRINT(fail);
                int tolerance = 49 * conductor.id * 0.005 + 3;
                // PRINT(tolerance);
                assert(fail < tolerance);
            }

            // releasing the outputs
            freeResponseMaps( &responseMaps, conductor.hack.m_visibleLandmarks_size );

        }
        // here comes the test
        // PRINT(cv::norm( ));
    }

    std::cout << "total elapsed time = " << elapsed_time / 1000000. << " s." << std::endl;
    //conductor.importer >> BOOST_SERIALIZATION_NVP(conductor.hack);

    return EXIT_SUCCESS;
}

// LuM end of file
<|endoftext|>


<commit_before>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/engine/post_commit_message_command.h"

#include <vector>

#include "chrome/browser/sync/engine/syncer_proto_util.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/sessions/sync_session.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/util/sync_types.h"

using std::vector;

namespace browser_sync {

PostCommitMessageCommand::PostCommitMessageCommand() {}
PostCommitMessageCommand::~PostCommitMessageCommand() {}

void PostCommitMessageCommand::ExecuteImpl(sessions::SyncSession* session) {
  if (session->status_controller()->commit_ids().empty())
    return;  // Nothing to commit.
  ClientToServerResponse response;
  syncable::ScopedDirLookup dir(session->context()->directory_manager(),
                                session->context()->account_name());
  if (!dir.good())
    return;
  sessions::StatusController* status = session->status_controller();
  if (!SyncerProtoUtil::PostClientToServerMessage(
      status->mutable_commit_message(), &response, session)) {
    // None of our changes got through, let's clear sync flags and wait for
    // another list update.
    status->increment_num_consecutive_problem_commits();
    status->increment_num_consecutive_errors();
    syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__);
    // TODO(sync): why set this flag, it seems like a bad side-effect?
    const vector<syncable::Id>& commit_ids = status->commit_ids();
    for (size_t i = 0; i < commit_ids.size(); i++) {
      syncable::MutableEntry entry(&trans, syncable::GET_BY_ID, commit_ids[i]);
      entry.Put(syncable::SYNCING, false);
    }
    return;
  } else {
    status->set_items_committed(true);
  }
  status->mutable_commit_response()->CopyFrom(response);
}

}  // namespace browser_sync
<commit_msg>Remove a TODO in post_commit_command.cc.  Clarify what's going on.<commit_after>// Copyright (c) 2006-2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/sync/engine/post_commit_message_command.h"

#include <vector>

#include "chrome/browser/sync/engine/syncer_proto_util.h"
#include "chrome/browser/sync/engine/syncproto.h"
#include "chrome/browser/sync/sessions/sync_session.h"
#include "chrome/browser/sync/syncable/directory_manager.h"
#include "chrome/browser/sync/util/sync_types.h"

using std::vector;

namespace browser_sync {

PostCommitMessageCommand::PostCommitMessageCommand() {}
PostCommitMessageCommand::~PostCommitMessageCommand() {}

void PostCommitMessageCommand::ExecuteImpl(sessions::SyncSession* session) {
  if (session->status_controller()->commit_ids().empty())
    return;  // Nothing to commit.
  ClientToServerResponse response;
  syncable::ScopedDirLookup dir(session->context()->directory_manager(),
                                session->context()->account_name());
  if (!dir.good())
    return;
  sessions::StatusController* status = session->status_controller();
  if (!SyncerProtoUtil::PostClientToServerMessage(
      status->mutable_commit_message(), &response, session)) {
    // None of our changes got through.  Clear the SYNCING bit which was
    // set to true during BuildCommitCommand, and which may still be true.
    // Not to be confused with IS_UNSYNCED.  This bit is used to detect local
    // changes to items that happen during the server Commit operation.
    status->increment_num_consecutive_problem_commits();
    status->increment_num_consecutive_errors();
    syncable::WriteTransaction trans(dir, syncable::SYNCER, __FILE__, __LINE__);
    const vector<syncable::Id>& commit_ids = status->commit_ids();
    for (size_t i = 0; i < commit_ids.size(); i++) {
      syncable::MutableEntry entry(&trans, syncable::GET_BY_ID, commit_ids[i]);
      entry.Put(syncable::SYNCING, false);
    }
    return;
  } else {
    status->set_items_committed(true);
  }
  status->mutable_commit_response()->CopyFrom(response);
}

}  // namespace browser_sync
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_FEATURE_HPP
#define MAPNIK_FEATURE_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/raster.hpp>

// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104000
#include <boost/property_map/property_map.hpp>
#else
#include <boost/property_map.hpp>
#endif
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

// stl
#include <map>

namespace mapnik {

typedef boost::shared_ptr<raster> raster_ptr;
typedef std::map<std::string,int> map_type;
typedef boost::associative_property_map<map_type> base_type;

class feature_impl;

class context : private boost::noncopyable,
                public base_type

{
    friend class feature_impl;
public:

    context()
        : base_type(mapping_) {}

    void insert(std::string const& name,int index)
    {
        mapping_.insert(std::make_pair(name,index));
    }

private:
    map_type mapping_;
};

typedef boost::shared_ptr<context> context_ptr;

class feature_impl : private boost::noncopyable
{
public:
    typedef mapnik::value value_type;
    typedef std::vector<value_type> cont_type;

    feature_impl(context_ptr const& ctx, int id)
        : id_(id),
          ctx_(ctx),
          data_(ctx_->mapping_.size())
    {}

    inline int id() const { return id_;}
    void set_id(int id) { id_ = id;}
    template <typename T>
    void set(std::string const& key, T const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = value(val);
        }
    }

    value_type const& get(std::string const& key) const
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            return data_[itr->second];
        }
        static const value_type default_value;
        return default_value;
    }

    boost::ptr_vector<geometry_type> & paths()
    {
        return geom_cont_;
    }

    void add_geometry(geometry_type * geom)
    {
       geom_cont_.push_back(geom);
    }

    unsigned num_geometries() const
    {
        return geom_cont_.size();
    }

    geometry_type const& get_geometry(unsigned index) const
    {
        return geom_cont_[index];
    }

    geometry_type& get_geometry(unsigned index)
    {
        return geom_cont_[index];
    }

    const raster_ptr& get_raster() const
    {
        return raster_;
    }

    void set_raster(raster_ptr const& raster)
    {
        raster_ = raster;
    }

    std::string to_string() const
    {
        std::stringstream ss;
        ss << "Feature (" << std::endl;
        map_type::const_iterator itr = ctx_->mapping_.begin();
        map_type::const_iterator end = ctx_->mapping_.end();
        for ( ;itr!=end; ++itr)
        {
            ss << "  " << itr->first  << ":" <<  data_[itr->second] << std::endl;
        }
        ss << ")" << std::endl;
        return ss.str();
    }

private:
    context_ptr ctx_;
    int id_;
    boost::ptr_vector<geometry_type> geom_cont_;
    raster_ptr raster_;

    cont_type data_;
};

inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
{
    out << f.to_string();
    return out;
}

typedef feature_impl Feature;

}

#endif // MAPNIK_FEATURE_HPP
<commit_msg>more friendly interface<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2011 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#ifndef MAPNIK_FEATURE_HPP
#define MAPNIK_FEATURE_HPP

// mapnik
#include <mapnik/value.hpp>
#include <mapnik/geometry.hpp>
#include <mapnik/raster.hpp>

// boost
#include <boost/version.hpp>
#if BOOST_VERSION >= 104000
#include <boost/property_map/property_map.hpp>
#else
#include <boost/property_map.hpp>
#endif
#include <boost/utility.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/scoped_ptr.hpp>

// stl
#include <map>

namespace mapnik {

typedef boost::shared_ptr<raster> raster_ptr;
typedef std::map<std::string,int> map_type;
typedef boost::associative_property_map<map_type> base_type;

class feature_impl;

class context : private boost::noncopyable,
                public base_type

{
    friend class feature_impl;
public:

    context()
        : base_type(mapping_) {}

    void push(std::string const& name)
    {
        mapping_.insert(std::make_pair(name,mapping_.size()));
    }

private:
    map_type mapping_;
};

typedef boost::shared_ptr<context> context_ptr;

class feature_impl : private boost::noncopyable
{
public:
    typedef mapnik::value value_type;
    typedef std::vector<value_type> cont_type;

    feature_impl(context_ptr const& ctx, int id)
        : id_(id),
          ctx_(ctx),
          data_(ctx_->mapping_.size())
    {}

    inline int id() const { return id_;}
    void set_id(int id) { id_ = id;}
    template <typename T>
    void set(std::string const& key, T const& val)
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            data_[itr->second] = value(val);
        }
    }

    value_type const& get(std::string const& key) const
    {
        map_type::const_iterator itr = ctx_->mapping_.find(key);
        if (itr != ctx_->mapping_.end())
        {
            return data_[itr->second];
        }
        static const value_type default_value;
        return default_value;
    }

    boost::ptr_vector<geometry_type> & paths()
    {
        return geom_cont_;
    }

    void add_geometry(geometry_type * geom)
    {
       geom_cont_.push_back(geom);
    }

    unsigned num_geometries() const
    {
        return geom_cont_.size();
    }

    geometry_type const& get_geometry(unsigned index) const
    {
        return geom_cont_[index];
    }

    geometry_type& get_geometry(unsigned index)
    {
        return geom_cont_[index];
    }

    const raster_ptr& get_raster() const
    {
        return raster_;
    }

    void set_raster(raster_ptr const& raster)
    {
        raster_ = raster;
    }

    std::string to_string() const
    {
        std::stringstream ss;
        ss << "Feature (" << std::endl;
        map_type::const_iterator itr = ctx_->mapping_.begin();
        map_type::const_iterator end = ctx_->mapping_.end();
        for ( ;itr!=end; ++itr)
        {
            ss << "  " << itr->first  << ":" <<  data_[itr->second] << std::endl;
        }
        ss << ")" << std::endl;
        return ss.str();
    }

private:
    context_ptr ctx_;
    int id_;
    boost::ptr_vector<geometry_type> geom_cont_;
    raster_ptr raster_;

    cont_type data_;
};

inline std::ostream& operator<< (std::ostream & out,feature_impl const& f)
{
    out << f.to_string();
    return out;
}

typedef feature_impl Feature;

}

#endif // MAPNIK_FEATURE_HPP
<|endoftext|>


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

#include "editor_run_native.h"

#include "editor_export.h"
#include "editor_node.h"
#include "editor_scale.h"

void EditorRunNative::_notification(int p_what) {

	if (p_what == NOTIFICATION_ENTER_TREE) {

		for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {

			Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(i);
			if (eep.is_null())
				continue;
			Ref<ImageTexture> icon = eep->get_run_icon();
			if (!icon.is_null()) {
				Ref<Image> im = icon->get_data();
				im = im->duplicate();
				im->clear_mipmaps();
				if (!im->empty()) {

					im->resize(16 * EDSCALE, 16 * EDSCALE);
					Ref<ImageTexture> small_icon;
					small_icon.instance();
					small_icon->create_from_image(im, 0);
					MenuButton *mb = memnew(MenuButton);
					mb->get_popup()->connect("id_pressed", this, "_run_native", varray(i));
					//mb->connect("pressed", this, "_run_native", varray(-1, i));
					mb->set_icon(small_icon);
					add_child(mb);
					menus[i] = mb;
				}
			}
		}
	}

	if (p_what == NOTIFICATION_PROCESS) {

		bool changed = EditorExport::get_singleton()->poll_export_platforms() || first;

		if (changed) {

			for (Map<int, MenuButton *>::Element *E = menus.front(); E; E = E->next()) {

				Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E->key());
				MenuButton *mb = E->get();
				int dc = eep->get_device_count();

				if (dc == 0) {
					mb->hide();
				} else {
					mb->get_popup()->clear();
					mb->show();
					mb->set_tooltip(TTR("Select device from the list"));
					for (int i = 0; i < dc; i++) {
						mb->get_popup()->add_icon_item(get_icon("Play", "EditorIcons"), eep->get_device_name(i));
						mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_device_info(i).strip_edges());
					}
				}
			}

			first = false;
		}
	}
}

void EditorRunNative::_run_native(int p_idx, int p_platform) {

	Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(p_platform);
	ERR_FAIL_COND(eep.is_null());
	/*if (p_idx == -1) {
		if (eep->get_device_count() == 1) {
			menus[p_platform]->get_popup()->hide();
			p_idx = 0;
		} else {
			return;
		}
	}*/

	Ref<EditorExportPreset> preset;

	for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {

		Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);
		if (ep->is_runnable() && ep->get_platform() == eep) {
			preset = ep;
			break;
		}
	}

	if (preset.is_null()) {
		EditorNode::get_singleton()->show_warning(TTR("No runnable export preset found for this platform.\nPlease add a runnable preset in the export menu."));
		return;
	}

	emit_signal("native_run");

	int flags = 0;
	if (deploy_debug_remote)
		flags |= EditorExportPlatform::DEBUG_FLAG_REMOTE_DEBUG;
	if (deploy_dumb)
		flags |= EditorExportPlatform::DEBUG_FLAG_DUMB_CLIENT;
	if (debug_collisions)
		flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_COLLISONS;
	if (debug_navigation)
		flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION;

	eep->run(preset, p_idx, flags);
}

void EditorRunNative::_bind_methods() {

	ClassDB::bind_method("_run_native", &EditorRunNative::_run_native);

	ADD_SIGNAL(MethodInfo("native_run"));
}

void EditorRunNative::set_deploy_dumb(bool p_enabled) {

	deploy_dumb = p_enabled;
}

bool EditorRunNative::is_deploy_dumb_enabled() const {

	return deploy_dumb;
}

void EditorRunNative::set_deploy_debug_remote(bool p_enabled) {

	deploy_debug_remote = p_enabled;
}

bool EditorRunNative::is_deploy_debug_remote_enabled() const {

	return deploy_debug_remote;
}

void EditorRunNative::set_debug_collisions(bool p_debug) {

	debug_collisions = p_debug;
}

bool EditorRunNative::get_debug_collisions() const {

	return debug_collisions;
}

void EditorRunNative::set_debug_navigation(bool p_debug) {

	debug_navigation = p_debug;
}

bool EditorRunNative::get_debug_navigation() const {

	return debug_navigation;
}

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

#include "editor_run_native.h"

#include "editor_export.h"
#include "editor_node.h"
#include "editor_scale.h"

void EditorRunNative::_notification(int p_what) {

	if (p_what == NOTIFICATION_ENTER_TREE) {

		for (int i = 0; i < EditorExport::get_singleton()->get_export_platform_count(); i++) {

			Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(i);
			if (eep.is_null())
				continue;
			Ref<ImageTexture> icon = eep->get_run_icon();
			if (!icon.is_null()) {
				Ref<Image> im = icon->get_data();
				im = im->duplicate();
				im->clear_mipmaps();
				if (!im->empty()) {

					im->resize(16 * EDSCALE, 16 * EDSCALE);
					Ref<ImageTexture> small_icon;
					small_icon.instance();
					small_icon->create_from_image(im, 0);
					MenuButton *mb = memnew(MenuButton);
					mb->get_popup()->connect("id_pressed", this, "_run_native", varray(i));
					mb->connect("pressed", this, "_run_native", varray(-1, i));
					mb->set_icon(small_icon);
					add_child(mb);
					menus[i] = mb;
				}
			}
		}
	}

	if (p_what == NOTIFICATION_PROCESS) {

		bool changed = EditorExport::get_singleton()->poll_export_platforms() || first;

		if (changed) {

			for (Map<int, MenuButton *>::Element *E = menus.front(); E; E = E->next()) {

				Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(E->key());
				MenuButton *mb = E->get();
				int dc = eep->get_device_count();

				if (dc == 0) {
					mb->hide();
				} else {
					mb->get_popup()->clear();
					mb->show();
					if (dc == 1) {
						mb->set_tooltip(eep->get_device_name(0) + "\n\n" + eep->get_device_info(0).strip_edges());
					} else {
						mb->set_tooltip("Select device from the list");
						for (int i = 0; i < dc; i++) {
							mb->get_popup()->add_icon_item(get_icon("Play", "EditorIcons"), eep->get_device_name(i));
							mb->get_popup()->set_item_tooltip(mb->get_popup()->get_item_count() - 1, eep->get_device_info(i).strip_edges());
						}
					}
				}
			}

			first = false;
		}
	}
}

void EditorRunNative::_run_native(int p_idx, int p_platform) {

	Ref<EditorExportPlatform> eep = EditorExport::get_singleton()->get_export_platform(p_platform);
	ERR_FAIL_COND(eep.is_null());

	if (p_idx == -1) {
		if (eep->get_device_count() == 1) {
			menus[p_platform]->get_popup()->hide();
			p_idx = 0;
		} else {
			return;
		}
	}

	Ref<EditorExportPreset> preset;

	for (int i = 0; i < EditorExport::get_singleton()->get_export_preset_count(); i++) {

		Ref<EditorExportPreset> ep = EditorExport::get_singleton()->get_export_preset(i);
		if (ep->is_runnable() && ep->get_platform() == eep) {
			preset = ep;
			break;
		}
	}

	if (preset.is_null()) {
		EditorNode::get_singleton()->show_warning(TTR("No runnable export preset found for this platform.\nPlease add a runnable preset in the export menu."));
		return;
	}

	emit_signal("native_run");

	int flags = 0;
	if (deploy_debug_remote)
		flags |= EditorExportPlatform::DEBUG_FLAG_REMOTE_DEBUG;
	if (deploy_dumb)
		flags |= EditorExportPlatform::DEBUG_FLAG_DUMB_CLIENT;
	if (debug_collisions)
		flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_COLLISONS;
	if (debug_navigation)
		flags |= EditorExportPlatform::DEBUG_FLAG_VIEW_NAVIGATION;

	eep->run(preset, p_idx, flags);
}

void EditorRunNative::_bind_methods() {

	ClassDB::bind_method("_run_native", &EditorRunNative::_run_native);

	ADD_SIGNAL(MethodInfo("native_run"));
}

void EditorRunNative::set_deploy_dumb(bool p_enabled) {

	deploy_dumb = p_enabled;
}

bool EditorRunNative::is_deploy_dumb_enabled() const {

	return deploy_dumb;
}

void EditorRunNative::set_deploy_debug_remote(bool p_enabled) {

	deploy_debug_remote = p_enabled;
}

bool EditorRunNative::is_deploy_debug_remote_enabled() const {

	return deploy_debug_remote;
}

void EditorRunNative::set_debug_collisions(bool p_debug) {

	debug_collisions = p_debug;
}

bool EditorRunNative::get_debug_collisions() const {

	return debug_collisions;
}

void EditorRunNative::set_debug_navigation(bool p_debug) {

	debug_navigation = p_debug;
}

bool EditorRunNative::get_debug_navigation() const {

	return debug_navigation;
}

EditorRunNative::EditorRunNative() {
	set_process(true);
	first = true;
	deploy_dumb = false;
	deploy_debug_remote = false;
	debug_collisions = false;
	debug_navigation = false;
}
<|endoftext|>


<commit_before>#pragma once
#include <map>
#include <vector>
#include <array>
#include "mtao/iterator/zip.hpp"

namespace mtao {
    template <typename IndexType>
        struct ReIndexer {
            IndexType add_index(IndexType idx) {
                if(auto it = m_forward.find(idx); it != m_forward.end()) {
                    return it->second;
                } else {
                    IndexType new_idx = m_forward.size();
                    return m_forward[idx] = new_idx;
                }
            }

            IndexType operator()(IndexType idx) {
                return add_index(idx);
            }
            IndexType get(IndexType idx) const {
                return m_forward[idx];
            }
            bool has_index(IndexType idx) const {
                return m_forward.find(idx) != m_forward.end();
            }
            std::vector<IndexType> inverse() const {
                std::vector<IndexType> ret(m_forward.size());
                for(auto&& [k,v]: m_forward) {
                    ret[v] = k;
                }
                return ret;
            }
            auto&& map() const { return m_forward; }
            size_t size() const { return m_forward.size(); }
            private:
            std::map<IndexType,IndexType> m_forward;
        };
    template <typename IndexType, size_t Size>
        struct StackedReIndexer {
            using RET = ReIndexer<IndexType>;
            template <size_t D>
            void add_index(IndexType idx) {
                indexers[D].add_index(idx);
                for(size_t i = D; i < Size; ++i) {
                    offsets[i+1] = offsets[i] + indexers[i].size();
                }
            }
            size_t size() const {
                return offsets[Size];
            }
            template <int D>
            bool has_index(IndexType idx) const {
                return indexers[D].has_index(idx);
            }
            std::vector<IndexType> inverse() const {
                std::vector<IndexType> ret(size());
                for(auto&& [i,o]: mtao::iterator::zip(indexers,offsets)) {
                    for(auto&& [k,v]: i.map()) {
                        ret[v + o] = k;
                    }
                }
                return ret;
            }
            std::array<RET,Size> indexers;
            std::array<size_t,Size+1> offsets = {};

        };
}
<commit_msg>updated reindexer<commit_after>#pragma once
#include <map>
#include <vector>
#include <array>
#include "mtao/iterator/zip.hpp"

namespace mtao {
    template <typename IndexType=int>
        struct ReIndexer {
            IndexType add_index(IndexType idx) {
                if(auto it = m_forward.find(idx); it != m_forward.end()) {
                    return it->second;
                } else {
                    IndexType new_idx = m_forward.size();
                    return m_forward[idx] = new_idx;
                }
            }
            IndexType set(IndexType idx, IndexType target) {
                return m_forward[idx] = target;
            }

            IndexType operator()(IndexType idx) {
                return add_index(idx);
            }
            IndexType get(IndexType idx) const {
                return m_forward[idx];
            }
            bool has_index(IndexType idx) const {
                return m_forward.find(idx) != m_forward.end();
            }
            std::vector<IndexType> inverse() const {
                std::vector<IndexType> ret(m_forward.size());
                for(auto&& [k,v]: m_forward) {
                    ret[v] = k;
                }
                return ret;
            }
            auto&& map() const { return m_forward; }
            size_t size() const { return m_forward.size(); }
            private:
            std::map<IndexType,IndexType> m_forward;
        };
    template <size_t Size, typename IndexType=int>
        struct StackedReIndexer {
            using RET = ReIndexer<IndexType>;
            template <size_t D>
                void add_index(IndexType idx) {
                    indexers[D].add_index(idx);
                    update_offsets(D);
                }
            template <size_t D>
                IndexType set(IndexType idx, IndexType target) {
                    indexers[D].set(idx,target);
                    update_offsets(D);
                }
            void add_index(IndexType idx, size_t D) {
                indexers[D].add_index(idx);
                update_offsets(D);
            }
            IndexType set(IndexType idx, IndexType target, size_t D) {
                indexers[D].set(idx,target);
                update_offsets(D);
            }
            void update_offsets(size_t D) {
                for(size_t i = D; i < Size; ++i) {
                    offsets[i+1] = offsets[i] + indexers[i].size();
                }
            }
            size_t size() const {
                return offsets[Size];
            }
            template <int D>
                bool has_index(IndexType idx) const {
                    return indexers[D].has_index(idx);
                }
            std::vector<IndexType> inverse() const {
                std::vector<IndexType> ret(size());
                for(auto&& [i,o]: mtao::iterator::zip(indexers,offsets)) {
                    for(auto&& [k,v]: i.map()) {
                        ret[v + o] = k;
                    }
                }
                return ret;
            }
            std::array<RET,Size> indexers;
            std::array<size_t,Size+1> offsets = {};

        };
}
<|endoftext|>


<commit_before>//----------------------------------------------------------------------------
/// \file stream_io.hpp
/// \author Serge Aleynikov
//----------------------------------------------------------------------------
/// Defines functions for stream input/output
//----------------------------------------------------------------------------
// Copyright (C) 2016 Serge Aleynikov <saleyn@gmail.com>
// Created: 2016-02-26
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is a part of utxx open-source project.

Copyright (C) 2016 Serge Aleynikov <saleyn@gmail.com>

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

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

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

***** END LICENSE BLOCK *****
*/
#pragma once

#include <iosfwd>
#include <utxx/convert.hpp>
#include <utxx/container/stack_container.hpp>

namespace utxx {

//------------------------------------------------------------------------------
/// Read \a a_cnt values from the input stream.
/// @param in       input stream.
/// @param a_output array of \a a_cnt double values.
/// @param a_fields array of \a a_cnt field positions (ascending order). If this
///                 value is NULL, the values are read from the input stream
///                 in consequitive order disregarding field positions.
/// @param a_cnt    count of values to read.
/// @param a_convert lambda used to convert a string value to type \a T:
///   const char* (const char* begin, const char* end, T& outout);
///   The function must return NULL if conversion is unsuccessful, or a pointer
///   past last successfully parsed character otherwise.
/// @return true if successfully read \a a_cnt values.
//------------------------------------------------------------------------------
template <typename T = double, int StrSize = 256, class Convert>
bool read_values(std::istream& in, T* a_output, int* a_fields, int a_cnt,
                 const Convert& a_convert)
{
  basic_stack_string<StrSize> str;

  auto& line = str.container();

  if (a_fields == nullptr) {
    for (int i=0; i < a_cnt; ++i) {
      if (in.eof()) return false;
      in >> *a_output++;
    }
  }
  else if (!std::getline(in, line))
    return false;
  else {
    const char* p = &*line.begin();
    const char* e = &*line.end();

    int fld = 0;

    auto ws      = [](char c)     { return c == ' ' || c == '\t'; };
    auto skip_ws = [&p, e, &ws]() { while (ws(*p) && p != e) p++; };

    for (int i=0; i < a_cnt; ++i, ++a_fields, ++a_output) {
      while (p != e) {
        skip_ws();
        if (++fld == *a_fields)
          break;
        while (!ws(*p) && p != e) p++;
      }

      if (fld != *a_fields)
        return false;

      p = a_convert(p, e, *a_output);

      if (!p)
          return false;
    }
  }

  return true;
}

} // namespace utxx<commit_msg>Require count to be greater than 0<commit_after>//----------------------------------------------------------------------------
/// \file stream_io.hpp
/// \author Serge Aleynikov
//----------------------------------------------------------------------------
/// Defines functions for stream input/output
//----------------------------------------------------------------------------
// Copyright (C) 2016 Serge Aleynikov <saleyn@gmail.com>
// Created: 2016-02-26
//----------------------------------------------------------------------------
/*
***** BEGIN LICENSE BLOCK *****

This file is a part of utxx open-source project.

Copyright (C) 2016 Serge Aleynikov <saleyn@gmail.com>

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

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

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

***** END LICENSE BLOCK *****
*/
#pragma once

#include <iosfwd>
#include <utxx/convert.hpp>
#include <utxx/container/stack_container.hpp>

namespace utxx {

//------------------------------------------------------------------------------
/// Read \a a_cnt values from the input stream.
/// @param in       input stream.
/// @param a_output array of \a a_cnt double values.
/// @param a_fields array of \a a_cnt field positions (ascending order). If this
///                 value is NULL, the values are read from the input stream
///                 in consequitive order disregarding field positions.
/// @param a_cnt    count of values to read (must be > 0).
/// @param a_convert lambda used to convert a string value to type \a T:
///   const char* (const char* begin, const char* end, T& outout);
///   The function must return NULL if conversion is unsuccessful, or a pointer
///   past last successfully parsed character otherwise.
/// @return true if successfully read \a a_cnt values.
//------------------------------------------------------------------------------
template <typename T = double, int StrSize = 256, class Convert>
bool read_values(std::istream& in, T* a_output, int* a_fields, int a_cnt,
                 const Convert& a_convert)
{
    assert(a_cnt);

    basic_stack_string<StrSize> str;

    auto& line = str.container();

    if (a_fields == nullptr) {
        for (int i=0; i < a_cnt; ++i) {
            if (in.eof()) return false;
            in >> *a_output++;
        }
    }
    else if (!std::getline(in, line))
        return false;
    else {
        const char* p = &*line.begin();
        const char* e = &*line.end();

        int fld = 0;

        auto ws      = [](char c)     { return c == ' ' || c == '\t'; };
        auto skip_ws = [&p, e, &ws]() { while (ws(*p) && p != e) p++; };

        for (int i=0; i < a_cnt; ++i, ++a_fields, ++a_output) {
            while (p != e) {
                skip_ws();
                if (++fld == *a_fields)
                    break;
                while (!ws(*p) && p != e) p++;
            }

            if (fld != *a_fields)
                return false;

            p = a_convert(p, e, *a_output);

            if (!p)
                return false;
        }
    }

    return true;
}

} // namespace utxx<|endoftext|>


<commit_before><commit_msg>Fix up tangents in MeshAssimp to help with #528.<commit_after><|endoftext|>


<commit_before>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE test_navimake
#include <boost/test/unit_test.hpp>
#include "boost/date_time/posix_time/posix_time_types.hpp"
#include "type/pt_data.h"
#include "type/type.h"
#include "type/response.pb.h"
#include "ed/build_helper.h"
#include "type/pb_converter.h"

using namespace navitia::type;
BOOST_AUTO_TEST_CASE(test_pt_displayinfo_destination) {
    ed::builder b("20120614");
    b.vj("A")("stop1", 8000, 8050);
    b.vj("A")("stop1", 8000, 8050);
    b.vj("V")("stop2", 8000, 8050);
    b.finish();
    b.data->build_uri();
    b.data->pt_data->index();
    b.data->build_raptor();

    auto pt_display_info = new pbnavitia::PtDisplayInfo();
    const Route* r = b.data->pt_data->routes_map["A:0"];
    boost::gregorian::date d1(2014,06,14);
    boost::posix_time::ptime t1(d1, boost::posix_time::seconds(10)); //10 sec after midnight
    boost::posix_time::ptime t2(d1, boost::posix_time::hours(10)); //10 hours after midnight
    boost::posix_time::time_period period(t1, t2);
    navitia::fill_pb_object(r, *b.data,
                            pt_display_info, 0,
                            {}, period, nullptr);
    BOOST_CHECK_EQUAL(pt_display_info->direction(), "stop1");
    pt_display_info->Clear();

    auto sp = new StopPoint();
    sp->name = "bob";
    navitia::fill_pb_object(r, *b.data,
                            pt_display_info, 0,
                            {}, period, sp);
    BOOST_CHECK_EQUAL(pt_display_info->direction(), "bob");
}
<commit_msg>kraken: add a test on fill_pb_object for route without vj<commit_after>/* Copyright © 2001-2014, Canal TP and/or its affiliates. All rights reserved.

This file is part of Navitia,
    the software to build cool stuff with public transport.

Hope you'll enjoy and contribute to this project,
    powered by Canal TP (www.canaltp.fr).
Help us simplify mobility and open public transport:
    a non ending quest to the responsive locomotion way of traveling!

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

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.

Stay tuned using
twitter @navitia
IRC #navitia on freenode
https://groups.google.com/d/forum/navitia
www.navitia.io
*/

#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE test_navimake
#include <boost/test/unit_test.hpp>
#include "boost/date_time/posix_time/posix_time_types.hpp"
#include "type/pt_data.h"
#include "type/type.h"
#include "type/response.pb.h"
#include "ed/build_helper.h"
#include "type/pb_converter.h"

using namespace navitia::type;
BOOST_AUTO_TEST_CASE(test_pt_displayinfo_destination) {
    ed::builder b("20120614");
    b.vj("A")("stop1", 8000, 8050);
    b.vj("A")("stop1", 8000, 8050);
    b.vj("V")("stop2", 8000, 8050);
    b.finish();
    b.data->build_uri();
    b.data->pt_data->index();
    b.data->build_raptor();

    auto pt_display_info = new pbnavitia::PtDisplayInfo();
    const Route* r = b.data->pt_data->routes_map["A:0"];
    boost::gregorian::date d1(2014,06,14);
    boost::posix_time::ptime t1(d1, boost::posix_time::seconds(10)); //10 sec after midnight
    boost::posix_time::ptime t2(d1, boost::posix_time::hours(10)); //10 hours after midnight
    boost::posix_time::time_period period(t1, t2);
    navitia::fill_pb_object(r, *b.data,
                            pt_display_info, 0,
                            {}, period, nullptr);
    BOOST_CHECK_EQUAL(pt_display_info->direction(), "stop1");
    pt_display_info->Clear();

    auto sp = new StopPoint();
    sp->name = "bob";
    navitia::fill_pb_object(r, *b.data,
                            pt_display_info, 0,
                            {}, period, sp);
    BOOST_CHECK_EQUAL(pt_display_info->direction(), "bob");
}

BOOST_AUTO_TEST_CASE(test_pt_displayinfo_destination_without_vj) {
    ed::builder b("20120614");
    auto* route = new Route();
    b.data->pt_data->routes.push_back(route);
    b.finish();
    b.data->build_uri();
    b.data->pt_data->index();
    b.data->build_raptor();

    auto pt_display_info = new pbnavitia::PtDisplayInfo();
    boost::gregorian::date d1(2014,06,14);
    boost::posix_time::ptime t1(d1, boost::posix_time::seconds(10)); //10 sec after midnight
    boost::posix_time::ptime t2(d1, boost::posix_time::hours(10)); //10 hours after midnight
    boost::posix_time::time_period period(t1, t2);
    navitia::fill_pb_object(route, *b.data,
                            pt_display_info, 0,
                            {}, period, nullptr);
    BOOST_CHECK_EQUAL(pt_display_info->direction(), "");
    pt_display_info->Clear();

}
<|endoftext|>


<commit_before>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/copresence/handlers/audio/audio_directive_handler.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "components/copresence/mediums/audio/audio_player.h"
#include "components/copresence/mediums/audio/audio_recorder.h"
#include "components/copresence/proto/data.pb.h"
#include "media/base/audio_bus.h"

namespace {

// UrlSafe is defined as:
// '/' represented by a '_' and '+' represented by a '-'
// TODO(rkc): Move this processing to the whispernet wrapper.
std::string FromUrlSafe(std::string token) {
  base::ReplaceChars(token, "-", "+", &token);
  base::ReplaceChars(token, "_", "/", &token);
  return token;
}

const int kSampleExpiryTimeMs = 60 * 60 * 1000;  // 60 minutes.
const int kMaxSamples = 10000;

}  // namespace

namespace copresence {

// Public methods.

AudioDirectiveHandler::AudioDirectiveHandler(
    const AudioRecorder::DecodeSamplesCallback& decode_cb,
    const AudioDirectiveHandler::EncodeTokenCallback& encode_cb)
    : player_audible_(NULL),
      player_inaudible_(NULL),
      recorder_(NULL),
      decode_cb_(decode_cb),
      encode_cb_(encode_cb),
      samples_cache_audible_(
          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
          kMaxSamples),
      samples_cache_inaudible_(
          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
          kMaxSamples) {
}

AudioDirectiveHandler::~AudioDirectiveHandler() {
  if (player_audible_)
    player_audible_->Finalize();
  if (player_inaudible_)
    player_inaudible_->Finalize();
  if (recorder_)
    recorder_->Finalize();
}

void AudioDirectiveHandler::Initialize() {
  player_audible_ = new AudioPlayer();
  player_audible_->Initialize();

  player_inaudible_ = new AudioPlayer();
  player_inaudible_->Initialize();

  recorder_ = new AudioRecorder(decode_cb_);
  recorder_->Initialize();
}

void AudioDirectiveHandler::AddInstruction(const TokenInstruction& instruction,
                                           const std::string& op_id,
                                           base::TimeDelta ttl) {
  switch (instruction.token_instruction_type()) {
    case TRANSMIT:
      DVLOG(2) << "Audio Transmit Directive received. Token: "
               << instruction.token_id()
               << " with TTL=" << ttl.InMilliseconds();
      switch (instruction.medium()) {
        case AUDIO_ULTRASOUND_PASSBAND:
          transmits_list_inaudible_.AddDirective(op_id, ttl);
          PlayToken(instruction.token_id(), false);
          break;
        case AUDIO_AUDIBLE_DTMF:
          transmits_list_audible_.AddDirective(op_id, ttl);
          PlayToken(instruction.token_id(), true);
          break;
        default:
          NOTREACHED();
      }
      break;
    case RECEIVE:
      DVLOG(2) << "Audio Receive Directive received. TTL="
               << ttl.InMilliseconds();
      receives_list_.AddDirective(op_id, ttl);
      ProcessNextReceive();
      break;
    case UNKNOWN_TOKEN_INSTRUCTION_TYPE:
    default:
      LOG(WARNING) << "Unknown Audio Transmit Directive received.";
  }
}

void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) {
  transmits_list_audible_.RemoveDirective(op_id);
  transmits_list_inaudible_.RemoveDirective(op_id);
  receives_list_.RemoveDirective(op_id);

  ProcessNextTransmit();
  ProcessNextReceive();
}

// Private methods.

void AudioDirectiveHandler::ProcessNextTransmit() {
  // If we have an active directive for audible or inaudible audio, ensure that
  // we are playing our respective token; if we do not have a directive, then
  // make sure we aren't playing. This is duplicate code, but for just two
  // elements, it has hard to make a case for processing a loop instead.

  scoped_ptr<AudioDirective> audible_transmit(
      transmits_list_audible_.GetActiveDirective());
  if (audible_transmit && !player_audible_->IsPlaying()) {
    DVLOG(3) << "Playing audible for op_id: " << audible_transmit->op_id;
    player_audible_->Play(
        samples_cache_audible_.GetValue(current_token_audible_));
    stop_audible_playback_timer_.Start(
        FROM_HERE,
        audible_transmit->end_time - base::Time::Now(),
        this,
        &AudioDirectiveHandler::ProcessNextTransmit);
  } else if (!audible_transmit && player_audible_->IsPlaying()) {
    DVLOG(3) << "Stopping audible playback.";
    current_token_audible_.clear();
    stop_audible_playback_timer_.Stop();
    player_audible_->Stop();
  }

  scoped_ptr<AudioDirective> inaudible_transmit(
      transmits_list_inaudible_.GetActiveDirective());
  if (inaudible_transmit && !player_inaudible_->IsPlaying()) {
    DVLOG(3) << "Playing inaudible for op_id: " << inaudible_transmit->op_id;
    player_inaudible_->Play(
        samples_cache_inaudible_.GetValue(current_token_inaudible_));
    stop_inaudible_playback_timer_.Start(
        FROM_HERE,
        inaudible_transmit->end_time - base::Time::Now(),
        this,
        &AudioDirectiveHandler::ProcessNextTransmit);
  } else if (!inaudible_transmit && player_inaudible_->IsPlaying()) {
    DVLOG(3) << "Stopping inaudible playback.";
    current_token_inaudible_.clear();
    stop_inaudible_playback_timer_.Stop();
    player_inaudible_->Stop();
  }
}

void AudioDirectiveHandler::ProcessNextReceive() {
  scoped_ptr<AudioDirective> receive(receives_list_.GetActiveDirective());

  if (receive && !recorder_->IsRecording()) {
    DVLOG(3) << "Recording for op_id: " << receive->op_id;
    recorder_->Record();
    stop_recording_timer_.Start(FROM_HERE,
                                receive->end_time - base::Time::Now(),
                                this,
                                &AudioDirectiveHandler::ProcessNextReceive);
  } else if (!receive && recorder_->IsRecording()) {
    DVLOG(3) << "Stopping Recording";
    stop_recording_timer_.Stop();
    recorder_->Stop();
  }
}

void AudioDirectiveHandler::PlayToken(const std::string token, bool audible) {
  std::string valid_token = FromUrlSafe(token);

  // If the token has been encoded already, use the cached samples.
  if (audible && samples_cache_audible_.HasKey(valid_token)) {
    current_token_audible_ = token;
    ProcessNextTransmit();
  } else if (!audible && samples_cache_inaudible_.HasKey(valid_token)) {
    current_token_inaudible_ = token;
    ProcessNextTransmit();
  } else {
    // Otherwise, encode the token and then play it.
    encode_cb_.Run(valid_token,
                   audible,
                   base::Bind(&AudioDirectiveHandler::PlayEncodedToken,
                              base::Unretained(this)));
  }
}

void AudioDirectiveHandler::PlayEncodedToken(
    const std::string& token,
    bool audible,
    const scoped_refptr<media::AudioBusRefCounted>& samples) {
  DVLOG(3) << "Token " << token << "[audible:" << audible << "] encoded.";
  if (audible) {
    samples_cache_audible_.Add(token, samples);
    current_token_audible_ = token;
    // Force process transmits to pick up the new token.
    if (player_audible_->IsPlaying())
      player_audible_->Stop();
  } else {
    samples_cache_inaudible_.Add(token, samples);
    current_token_inaudible_ = token;
    // Force process transmits to pick up the new token.
    if (player_inaudible_->IsPlaying())
      player_inaudible_->Stop();
  }

  ProcessNextTransmit();
}

}  // namespace copresence
<commit_msg>Fix race in audio playback.<commit_after>// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "components/copresence/handlers/audio/audio_directive_handler.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/strings/string_util.h"
#include "base/time/time.h"
#include "components/copresence/mediums/audio/audio_player.h"
#include "components/copresence/mediums/audio/audio_recorder.h"
#include "components/copresence/proto/data.pb.h"
#include "media/base/audio_bus.h"

namespace {

// UrlSafe is defined as:
// '/' represented by a '_' and '+' represented by a '-'
// TODO(rkc): Move this processing to the whispernet wrapper.
std::string FromUrlSafe(std::string token) {
  base::ReplaceChars(token, "-", "+", &token);
  base::ReplaceChars(token, "_", "/", &token);
  return token;
}

const int kSampleExpiryTimeMs = 60 * 60 * 1000;  // 60 minutes.
const int kMaxSamples = 10000;

}  // namespace

namespace copresence {

// Public methods.

AudioDirectiveHandler::AudioDirectiveHandler(
    const AudioRecorder::DecodeSamplesCallback& decode_cb,
    const AudioDirectiveHandler::EncodeTokenCallback& encode_cb)
    : player_audible_(NULL),
      player_inaudible_(NULL),
      recorder_(NULL),
      decode_cb_(decode_cb),
      encode_cb_(encode_cb),
      samples_cache_audible_(
          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
          kMaxSamples),
      samples_cache_inaudible_(
          base::TimeDelta::FromMilliseconds(kSampleExpiryTimeMs),
          kMaxSamples) {
}

AudioDirectiveHandler::~AudioDirectiveHandler() {
  if (player_audible_)
    player_audible_->Finalize();
  if (player_inaudible_)
    player_inaudible_->Finalize();
  if (recorder_)
    recorder_->Finalize();
}

void AudioDirectiveHandler::Initialize() {
  player_audible_ = new AudioPlayer();
  player_audible_->Initialize();

  player_inaudible_ = new AudioPlayer();
  player_inaudible_->Initialize();

  recorder_ = new AudioRecorder(decode_cb_);
  recorder_->Initialize();
}

void AudioDirectiveHandler::AddInstruction(const TokenInstruction& instruction,
                                           const std::string& op_id,
                                           base::TimeDelta ttl) {
  switch (instruction.token_instruction_type()) {
    case TRANSMIT:
      DVLOG(2) << "Audio Transmit Directive received. Token: "
               << instruction.token_id()
               << " with TTL=" << ttl.InMilliseconds();
      switch (instruction.medium()) {
        case AUDIO_ULTRASOUND_PASSBAND:
          transmits_list_inaudible_.AddDirective(op_id, ttl);
          PlayToken(instruction.token_id(), false);
          break;
        case AUDIO_AUDIBLE_DTMF:
          transmits_list_audible_.AddDirective(op_id, ttl);
          PlayToken(instruction.token_id(), true);
          break;
        default:
          NOTREACHED();
      }
      break;
    case RECEIVE:
      DVLOG(2) << "Audio Receive Directive received. TTL="
               << ttl.InMilliseconds();
      receives_list_.AddDirective(op_id, ttl);
      ProcessNextReceive();
      break;
    case UNKNOWN_TOKEN_INSTRUCTION_TYPE:
    default:
      LOG(WARNING) << "Unknown Audio Transmit Directive received.";
  }
}

void AudioDirectiveHandler::RemoveInstructions(const std::string& op_id) {
  transmits_list_audible_.RemoveDirective(op_id);
  transmits_list_inaudible_.RemoveDirective(op_id);
  receives_list_.RemoveDirective(op_id);

  ProcessNextTransmit();
  ProcessNextReceive();
}

// Private methods.

void AudioDirectiveHandler::ProcessNextTransmit() {
  // If we have an active directive for audible or inaudible audio, ensure that
  // we are playing our respective token; if we do not have a directive, then
  // make sure we aren't playing. This is duplicate code, but for just two
  // elements, it has hard to make a case for processing a loop instead.

  scoped_ptr<AudioDirective> audible_transmit(
      transmits_list_audible_.GetActiveDirective());
  if (audible_transmit && !player_audible_->IsPlaying() &&
      samples_cache_audible_.HasKey(current_token_audible_)) {
    DVLOG(3) << "Playing audible for op_id: " << audible_transmit->op_id;
    player_audible_->Play(
        samples_cache_audible_.GetValue(current_token_audible_));
    stop_audible_playback_timer_.Start(
        FROM_HERE,
        audible_transmit->end_time - base::Time::Now(),
        this,
        &AudioDirectiveHandler::ProcessNextTransmit);
  } else if (!audible_transmit && player_audible_->IsPlaying()) {
    DVLOG(3) << "Stopping audible playback.";
    current_token_audible_.clear();
    stop_audible_playback_timer_.Stop();
    player_audible_->Stop();
  }

  scoped_ptr<AudioDirective> inaudible_transmit(
      transmits_list_inaudible_.GetActiveDirective());
  if (inaudible_transmit && !player_inaudible_->IsPlaying() &&
      samples_cache_inaudible_.HasKey(current_token_inaudible_)) {
    DVLOG(3) << "Playing inaudible for op_id: " << inaudible_transmit->op_id;
    player_inaudible_->Play(
        samples_cache_inaudible_.GetValue(current_token_inaudible_));
    stop_inaudible_playback_timer_.Start(
        FROM_HERE,
        inaudible_transmit->end_time - base::Time::Now(),
        this,
        &AudioDirectiveHandler::ProcessNextTransmit);
  } else if (!inaudible_transmit && player_inaudible_->IsPlaying()) {
    DVLOG(3) << "Stopping inaudible playback.";
    current_token_inaudible_.clear();
    stop_inaudible_playback_timer_.Stop();
    player_inaudible_->Stop();
  }
}

void AudioDirectiveHandler::ProcessNextReceive() {
  scoped_ptr<AudioDirective> receive(receives_list_.GetActiveDirective());

  if (receive && !recorder_->IsRecording()) {
    DVLOG(3) << "Recording for op_id: " << receive->op_id;
    recorder_->Record();
    stop_recording_timer_.Start(FROM_HERE,
                                receive->end_time - base::Time::Now(),
                                this,
                                &AudioDirectiveHandler::ProcessNextReceive);
  } else if (!receive && recorder_->IsRecording()) {
    DVLOG(3) << "Stopping Recording";
    stop_recording_timer_.Stop();
    recorder_->Stop();
  }
}

void AudioDirectiveHandler::PlayToken(const std::string token, bool audible) {
  std::string valid_token = FromUrlSafe(token);

  // If the token has been encoded already, use the cached samples.
  if (audible && samples_cache_audible_.HasKey(valid_token)) {
    current_token_audible_ = token;
    ProcessNextTransmit();
  } else if (!audible && samples_cache_inaudible_.HasKey(valid_token)) {
    current_token_inaudible_ = token;
    ProcessNextTransmit();
  } else {
    // Otherwise, encode the token and then play it.
    encode_cb_.Run(valid_token,
                   audible,
                   base::Bind(&AudioDirectiveHandler::PlayEncodedToken,
                              base::Unretained(this)));
  }
}

void AudioDirectiveHandler::PlayEncodedToken(
    const std::string& token,
    bool audible,
    const scoped_refptr<media::AudioBusRefCounted>& samples) {
  DVLOG(3) << "Token " << token << "[audible:" << audible << "] encoded.";
  if (audible) {
    samples_cache_audible_.Add(token, samples);
    current_token_audible_ = token;
    // Force process transmits to pick up the new token.
    if (player_audible_->IsPlaying())
      player_audible_->Stop();
  } else {
    samples_cache_inaudible_.Add(token, samples);
    current_token_inaudible_ = token;
    // Force process transmits to pick up the new token.
    if (player_inaudible_->IsPlaying())
      player_inaudible_->Stop();
  }

  ProcessNextTransmit();
}

}  // namespace copresence
<|endoftext|>