<commit_before>#include "Renderer.hpp"

static const char* defaultVertShader = AL_STRINGIFY
(
    void main(void)
    {
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    }
);

static const char* yuvGammaFragShader = AL_STRINGIFY
(
    uniform sampler2D yTexture;
    uniform sampler2D uTexture;
    uniform sampler2D vTexture;

    uniform float gamma_pow;
    uniform float gamma_min;
    uniform float gamma_max;

    void main(void)
    {
        float y = texture2D(yTexture, gl_TexCoord[0].st).r;
        float u = texture2D(uTexture, gl_TexCoord[0].st).r;
        float v = texture2D(vTexture, gl_TexCoord[0].st).r;

        // YUV -> RGB
        vec4 color;
        color.r = 1.164 * (y - 16.0/255.0)                             + 2.018 * (v - 128.0/255.0);
        color.g = 1.164 * (y - 16.0/255.0) - 0.813 * (u - 128.0/255.0) - 0.391 * (v - 128.0/255.0);
        color.b = 1.164 * (y - 16.0/255.0) + 1.596 * (u - 128.0/255.0);

        // Gamma
        color.r = pow(clamp(color.r, gamma_min, gamma_max), gamma_pow);
        color.g = pow(clamp(color.g, gamma_min, gamma_max), gamma_pow);
        color.b = pow(clamp(color.b, gamma_min, gamma_max), gamma_pow);
        gl_FragColor = color;
    }
);

Renderer::Renderer()
    :
    al::OmniApp("AlloPlayer", false, 2048), gammaMin(0.0f), gammaMax(1.0f), gammaPow(1.0f),
    forRotation(0, 0, 0), forAngle(M_PI*2.0), rotation(0, 0, 0), rotationSpeed(0.01)
{
    nav().smooth(0.8);

    for (int i = 0; i < 1; i++)
    {
        cubemapPool.push(nullptr);
    }

    for (int i = 0; i < StereoCubemap::MAX_EYES_COUNT * Cubemap::MAX_FACES_COUNT; i++)
    {
        textures.push_back(YUV420PTexture());
    }
}

Renderer::~Renderer()
{
}

bool Renderer::onCreate()
{
    std::cout << "OpenGL version: " << glGetString(GL_VERSION) << ", GLSL version " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    al::Shader vert, frag;
    vert.source(defaultVertShader, al::Shader::VERTEX).compile();
    vert.printLog();
    frag.source(yuvGammaFragShader, al::Shader::FRAGMENT).compile();
    frag.printLog();
    yuvGammaShader.attach(vert).attach(frag).link();
    yuvGammaShader.printLog();

    return OmniApp::onCreate();
}

bool Renderer::onFrame()
{
    now = al::MainLoop::now();

    StereoCubemap* cubemap;
    if (cubemapBuffer.try_pop(cubemap))
    {
        for (int j = 0; j < cubemap->getEyesCount(); j++)
        {
            Cubemap* eye = cubemap->getEye(j);
            for (int i = 0; i < eye->getFacesCount(); i++)
            {
                CubemapFace* face = eye->getFace(i);

                // Reorder faces so that they are displayed correctly in the AlloSphere
                int texI;
                if (i == 0)
                {
                    texI = 1;
                }
                else if (i == 1)
                {
                    texI = 0;
                }
                else if (i == 2)
                {
                    texI = 4;
                }
                else if (i == 3)
                {
                    texI = 5;
                }
                else if (i == 4)
                {
                    texI = 2;
                }
                else if (i == 5)
                {
                    texI = 3;
                }
                else
                {
                    texI = i;
                }
                YUV420PTexture& tex = textures[texI + j * Cubemap::MAX_FACES_COUNT];

                if (face)
                {
                    // create texture if not already created
                    if (!tex.yTexture)
                    {
                        tex.yTexture = new al::Texture(face->getContent()->getWidth(),
                                                       face->getContent()->getHeight(),
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        tex.uTexture = new al::Texture(face->getContent()->getWidth()/2,
                                                       face->getContent()->getHeight()/2,
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        tex.vTexture = new al::Texture(face->getContent()->getWidth()/2,
                                                       face->getContent()->getHeight()/2,
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        textures[texI + j * Cubemap::MAX_FACES_COUNT] = tex;

                        // In case a face is mono use the same the texture for left and right.
                        // By doing so, image will become twice as bright in the AlloSphere.
                        if (j == 0 && cubemap->getEyesCount() > 1 && cubemap->getEye(1)->getFacesCount() <= i)
                        {
                            textures[texI + Cubemap::MAX_FACES_COUNT] = tex;
                        }
                    }

                    tex.yTexture->bind();
                    glTexSubImage2D(tex.yTexture->target(), 0,
                                    0, 0,
                                    tex.yTexture->width(),
                                    tex.yTexture->height(),
                                    tex.yTexture->format(),
                                    tex.yTexture->type(),
                                    face->getContent()->getPixels());
                    tex.vTexture->bind();
                    glTexSubImage2D(tex.vTexture->target(), 0,
                                    0, 0,
                                    tex.vTexture->width(),
                                    tex.vTexture->height(),
                                    tex.vTexture->format(),
                                    tex.vTexture->type(),
                                    (char*)face->getContent()->getPixels() +
                                        face->getContent()->getWidth() * face->getContent()->getHeight());
                    tex.uTexture->bind();
                    glTexSubImage2D(tex.uTexture->target(), 0,
                                    0, 0,
                                    tex.uTexture->width(),
                                    tex.uTexture->height(),
                                    tex.uTexture->format(),
                                    tex.uTexture->type(),
                                    (char*)face->getContent()->getPixels() +
                                        face->getContent()->getWidth() * face->getContent()->getHeight() +
                                        (face->getContent()->getWidth()/2) * (face->getContent()->getHeight()/2));
                    tex.uTexture->unbind();

                    if (onDisplayedCubemapFace) onDisplayedCubemapFace(this, i + j * Cubemap::MAX_FACES_COUNT);
                }
            }
        }

        cubemapPool.push(cubemap);
    }

    // Set uniforms
    {
        boost::mutex::scoped_lock(uniformsMutex);
        yuvGammaShader.begin();
        yuvGammaShader.uniform("gamma_min", gammaMin);
        yuvGammaShader.uniform("gamma_max", gammaMax);
        yuvGammaShader.uniform("gamma_pow", gammaPow);
        yuvGammaShader.end();
        mOmni.forRotation(forRotation);
        mOmni.forAngle(forAngle);
        mOmni.rotation(rotation);
    }

    bool result = OmniApp::onFrame();

    if (onDisplayedFrame) onDisplayedFrame(this);
    return result;
}

StereoCubemap* Renderer::onNextCubemap(CubemapSource* source, StereoCubemap* cubemap)
{
    StereoCubemap* oldCubemap;
    if (!cubemapPool.try_pop(oldCubemap))
    {
        if (cubemapPool.closed())
        {
            abort();
        }
        else
        {
            return cubemap;
        }
    }

    cubemapBuffer.push(cubemap);
    return oldCubemap;
}

void Renderer::onDraw(al::Graphics& gl)
{
    int faceIndex = mOmni.face();
    int eyeIndex = (mOmni.eye() <= 0.0f) ? 0 : 1;
    YUV420PTexture& tex = textures[faceIndex + eyeIndex * Cubemap::MAX_FACES_COUNT];

    // render cubemap
    if (tex.yTexture)
    {
        // Configure gamma to make backdrop more visible in the AlloSphere
        yuvGammaShader.begin();

        // Borrow a temporary Mesh from Graphics
        al::Mesh& m = gl.mesh();

        m.reset();

        // Generate geometry
        m.primitive(al::Graphics::TRIANGLE_STRIP);
        m.vertex(-1,  1);
        m.vertex(-1, -1);
        m.vertex( 1,  1);
        m.vertex( 1, -1);

        // Add texture coordinates and flip cubemap
        m.texCoord(1,1);
        m.texCoord(1,0);
        m.texCoord(0,1);
        m.texCoord(0,0);

        // We must tell the GPU to use the texture when rendering primitives
        tex.yTexture->bind(0);
        tex.vTexture->bind(1);
        tex.uTexture->bind(2);

        yuvGammaShader.uniform("yTexture", 0);
        yuvGammaShader.uniform("uTexture", 1);
        yuvGammaShader.uniform("vTexture", 2);

        gl.draw(m);

        tex.yTexture->unbind(0);
        tex.vTexture->unbind(1);
        tex.uTexture->unbind(2);

        yuvGammaShader.end();
    }
}

void Renderer::onMessage(al::osc::Message& m)
{
    OmniApp::onMessage(m);

    m.resetStream();
    if (m.addressPattern() == "/ty")
    {
        float x;
        m >> x;
        setRotation(al::Vec3f(0, rotation[1]-x/rotationSpeed, 0));
    }
}

bool Renderer::onKeyDown(const al::Keyboard& k)
{
    return true;
}

void Renderer::setOnDisplayedFrame(const std::function<void (Renderer*)>& callback)
{
    onDisplayedFrame = callback;
}

void Renderer::setOnDisplayedCubemapFace(const std::function<void (Renderer*, int)>& callback)
{
    onDisplayedCubemapFace = callback;
}

void Renderer::setGammaMin(float gammaMin)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaMin = gammaMin;
}

void Renderer::setGammaMax(float gammaMax)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaMax = gammaMax;
}

void Renderer::setGammaPow(float gammaPow)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaPow = gammaPow;
}

void Renderer::setFORRotation(const al::Vec3f& forRotation)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->forRotation = forRotation;
}

void Renderer::setFORAngle(float forAngle)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->forAngle = forAngle;
}

void Renderer::setRotation(const al::Vec3f& rotation)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->rotation = rotation;
}

void Renderer::setRotationSpeed(float speed)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->rotationSpeed = speed;
}

void Renderer::setCubemapSource(CubemapSource* cubemapSource)
{
    cubemapSource->setOnNextCubemap(boost::bind(&Renderer::onNextCubemap,
                                                this,
                                                _1,
                                                _2));
}

float Renderer::getGammaMin()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaMin;
}

float Renderer::getGammaMax()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaMax;
}

float Renderer::getGammaPow()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaPow;
}

const al::Vec3f& Renderer::getFORRotation()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return forRotation;
}

float Renderer::getFORAngle()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return forAngle;
}

const al::Vec3f& Renderer::getRotation()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return rotation;
}

float Renderer::getRotationSpeed()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return rotationSpeed;
}
<commit_msg>Improved rotation speed.<commit_after>#include "Renderer.hpp"

static const char* defaultVertShader = AL_STRINGIFY
(
    void main(void)
    {
        gl_TexCoord[0] = gl_MultiTexCoord0;
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    }
);

static const char* yuvGammaFragShader = AL_STRINGIFY
(
    uniform sampler2D yTexture;
    uniform sampler2D uTexture;
    uniform sampler2D vTexture;

    uniform float gamma_pow;
    uniform float gamma_min;
    uniform float gamma_max;

    void main(void)
    {
        float y = texture2D(yTexture, gl_TexCoord[0].st).r;
        float u = texture2D(uTexture, gl_TexCoord[0].st).r;
        float v = texture2D(vTexture, gl_TexCoord[0].st).r;

        // YUV -> RGB
        vec4 color;
        color.r = 1.164 * (y - 16.0/255.0)                             + 2.018 * (v - 128.0/255.0);
        color.g = 1.164 * (y - 16.0/255.0) - 0.813 * (u - 128.0/255.0) - 0.391 * (v - 128.0/255.0);
        color.b = 1.164 * (y - 16.0/255.0) + 1.596 * (u - 128.0/255.0);

        // Gamma
        color.r = pow(clamp(color.r, gamma_min, gamma_max), gamma_pow);
        color.g = pow(clamp(color.g, gamma_min, gamma_max), gamma_pow);
        color.b = pow(clamp(color.b, gamma_min, gamma_max), gamma_pow);
        gl_FragColor = color;
    }
);

Renderer::Renderer()
    :
    al::OmniApp("AlloPlayer", false, 2048), gammaMin(0.0f), gammaMax(1.0f), gammaPow(1.0f),
    forRotation(0, 0, 0), forAngle(M_PI*2.0), rotation(0, 0, 0), rotationSpeed(0.5)
{
    nav().smooth(0.8);

    for (int i = 0; i < 1; i++)
    {
        cubemapPool.push(nullptr);
    }

    for (int i = 0; i < StereoCubemap::MAX_EYES_COUNT * Cubemap::MAX_FACES_COUNT; i++)
    {
        textures.push_back(YUV420PTexture());
    }
}

Renderer::~Renderer()
{
}

bool Renderer::onCreate()
{
    std::cout << "OpenGL version: " << glGetString(GL_VERSION) << ", GLSL version " << glGetString(GL_SHADING_LANGUAGE_VERSION) << std::endl;

    al::Shader vert, frag;
    vert.source(defaultVertShader, al::Shader::VERTEX).compile();
    vert.printLog();
    frag.source(yuvGammaFragShader, al::Shader::FRAGMENT).compile();
    frag.printLog();
    yuvGammaShader.attach(vert).attach(frag).link();
    yuvGammaShader.printLog();

    return OmniApp::onCreate();
}

bool Renderer::onFrame()
{
    now = al::MainLoop::now();

    StereoCubemap* cubemap;
    if (cubemapBuffer.try_pop(cubemap))
    {
        for (int j = 0; j < cubemap->getEyesCount(); j++)
        {
            Cubemap* eye = cubemap->getEye(j);
            for (int i = 0; i < eye->getFacesCount(); i++)
            {
                CubemapFace* face = eye->getFace(i);

                // Reorder faces so that they are displayed correctly in the AlloSphere
                int texI;
                if (i == 0)
                {
                    texI = 1;
                }
                else if (i == 1)
                {
                    texI = 0;
                }
                else if (i == 2)
                {
                    texI = 4;
                }
                else if (i == 3)
                {
                    texI = 5;
                }
                else if (i == 4)
                {
                    texI = 2;
                }
                else if (i == 5)
                {
                    texI = 3;
                }
                else
                {
                    texI = i;
                }
                YUV420PTexture& tex = textures[texI + j * Cubemap::MAX_FACES_COUNT];

                if (face)
                {
                    // create texture if not already created
                    if (!tex.yTexture)
                    {
                        tex.yTexture = new al::Texture(face->getContent()->getWidth(),
                                                       face->getContent()->getHeight(),
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        tex.uTexture = new al::Texture(face->getContent()->getWidth()/2,
                                                       face->getContent()->getHeight()/2,
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        tex.vTexture = new al::Texture(face->getContent()->getWidth()/2,
                                                       face->getContent()->getHeight()/2,
                                                       al::Graphics::LUMINANCE,
                                                       al::Graphics::UBYTE);
                        textures[texI + j * Cubemap::MAX_FACES_COUNT] = tex;

                        // In case a face is mono use the same the texture for left and right.
                        // By doing so, image will become twice as bright in the AlloSphere.
                        if (j == 0 && cubemap->getEyesCount() > 1 && cubemap->getEye(1)->getFacesCount() <= i)
                        {
                            textures[texI + Cubemap::MAX_FACES_COUNT] = tex;
                        }
                    }

                    tex.yTexture->bind();
                    glTexSubImage2D(tex.yTexture->target(), 0,
                                    0, 0,
                                    tex.yTexture->width(),
                                    tex.yTexture->height(),
                                    tex.yTexture->format(),
                                    tex.yTexture->type(),
                                    face->getContent()->getPixels());
                    tex.vTexture->bind();
                    glTexSubImage2D(tex.vTexture->target(), 0,
                                    0, 0,
                                    tex.vTexture->width(),
                                    tex.vTexture->height(),
                                    tex.vTexture->format(),
                                    tex.vTexture->type(),
                                    (char*)face->getContent()->getPixels() +
                                        face->getContent()->getWidth() * face->getContent()->getHeight());
                    tex.uTexture->bind();
                    glTexSubImage2D(tex.uTexture->target(), 0,
                                    0, 0,
                                    tex.uTexture->width(),
                                    tex.uTexture->height(),
                                    tex.uTexture->format(),
                                    tex.uTexture->type(),
                                    (char*)face->getContent()->getPixels() +
                                        face->getContent()->getWidth() * face->getContent()->getHeight() +
                                        (face->getContent()->getWidth()/2) * (face->getContent()->getHeight()/2));
                    tex.uTexture->unbind();

                    if (onDisplayedCubemapFace) onDisplayedCubemapFace(this, i + j * Cubemap::MAX_FACES_COUNT);
                }
            }
        }

        cubemapPool.push(cubemap);
    }

    // Set uniforms
    {
        boost::mutex::scoped_lock(uniformsMutex);
        yuvGammaShader.begin();
        yuvGammaShader.uniform("gamma_min", gammaMin);
        yuvGammaShader.uniform("gamma_max", gammaMax);
        yuvGammaShader.uniform("gamma_pow", gammaPow);
        yuvGammaShader.end();
        mOmni.forRotation(forRotation);
        mOmni.forAngle(forAngle);
        mOmni.rotation(rotation);
    }

    bool result = OmniApp::onFrame();

    if (onDisplayedFrame) onDisplayedFrame(this);
    return result;
}

StereoCubemap* Renderer::onNextCubemap(CubemapSource* source, StereoCubemap* cubemap)
{
    StereoCubemap* oldCubemap;
    if (!cubemapPool.try_pop(oldCubemap))
    {
        if (cubemapPool.closed())
        {
            abort();
        }
        else
        {
            return cubemap;
        }
    }

    cubemapBuffer.push(cubemap);
    return oldCubemap;
}

void Renderer::onDraw(al::Graphics& gl)
{
    int faceIndex = mOmni.face();
    int eyeIndex = (mOmni.eye() <= 0.0f) ? 0 : 1;
    YUV420PTexture& tex = textures[faceIndex + eyeIndex * Cubemap::MAX_FACES_COUNT];

    // render cubemap
    if (tex.yTexture)
    {
        // Configure gamma to make backdrop more visible in the AlloSphere
        yuvGammaShader.begin();

        // Borrow a temporary Mesh from Graphics
        al::Mesh& m = gl.mesh();

        m.reset();

        // Generate geometry
        m.primitive(al::Graphics::TRIANGLE_STRIP);
        m.vertex(-1,  1);
        m.vertex(-1, -1);
        m.vertex( 1,  1);
        m.vertex( 1, -1);

        // Add texture coordinates and flip cubemap
        m.texCoord(1,1);
        m.texCoord(1,0);
        m.texCoord(0,1);
        m.texCoord(0,0);

        // We must tell the GPU to use the texture when rendering primitives
        tex.yTexture->bind(0);
        tex.vTexture->bind(1);
        tex.uTexture->bind(2);

        yuvGammaShader.uniform("yTexture", 0);
        yuvGammaShader.uniform("uTexture", 1);
        yuvGammaShader.uniform("vTexture", 2);

        gl.draw(m);

        tex.yTexture->unbind(0);
        tex.vTexture->unbind(1);
        tex.uTexture->unbind(2);

        yuvGammaShader.end();
    }
}

void Renderer::onMessage(al::osc::Message& m)
{
    OmniApp::onMessage(m);

    m.resetStream();
    if (m.addressPattern() == "/ty")
    {
        float x;
        m >> x;
        setRotation(al::Vec3f(0, rotation[1]-x*rotationSpeed*0.01, 0));
    }
}

bool Renderer::onKeyDown(const al::Keyboard& k)
{
    return true;
}

void Renderer::setOnDisplayedFrame(const std::function<void (Renderer*)>& callback)
{
    onDisplayedFrame = callback;
}

void Renderer::setOnDisplayedCubemapFace(const std::function<void (Renderer*, int)>& callback)
{
    onDisplayedCubemapFace = callback;
}

void Renderer::setGammaMin(float gammaMin)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaMin = gammaMin;
}

void Renderer::setGammaMax(float gammaMax)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaMax = gammaMax;
}

void Renderer::setGammaPow(float gammaPow)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->gammaPow = gammaPow;
}

void Renderer::setFORRotation(const al::Vec3f& forRotation)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->forRotation = forRotation;
}

void Renderer::setFORAngle(float forAngle)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->forAngle = forAngle;
}

void Renderer::setRotation(const al::Vec3f& rotation)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->rotation = rotation;
}

void Renderer::setRotationSpeed(float speed)
{
    boost::mutex::scoped_lock(uniformsMutex);
    this->rotationSpeed = speed;
}

void Renderer::setCubemapSource(CubemapSource* cubemapSource)
{
    cubemapSource->setOnNextCubemap(boost::bind(&Renderer::onNextCubemap,
                                                this,
                                                _1,
                                                _2));
}

float Renderer::getGammaMin()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaMin;
}

float Renderer::getGammaMax()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaMax;
}

float Renderer::getGammaPow()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return gammaPow;
}

const al::Vec3f& Renderer::getFORRotation()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return forRotation;
}

float Renderer::getFORAngle()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return forAngle;
}

const al::Vec3f& Renderer::getRotation()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return rotation;
}

float Renderer::getRotationSpeed()
{
    boost::mutex::scoped_lock(uniformsMutex);
    return rotationSpeed;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: collator_unicode.hxx,v $
 *
 *  $Revision: 1.11 $
 *
 *  last change: $Author: kz $ $Date: 2006-12-12 16:12:21 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _I18N_COLLATOR_UNICODE_HXX_
#define _I18N_COLLATOR_UNICODE_HXX_

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/i18n/XCollator.hpp>
#include <cppuhelper/implbase1.hxx>
#include <osl/module.h>

#include "warnings_guard_unicode_tblcoll.h"

//      ----------------------------------------------------
//      class Collator_Unicode
//      ----------------------------------------------------

namespace com { namespace sun { namespace star { namespace i18n {

class Collator_Unicode : public cppu::WeakImplHelper1 < XCollator >
{
public:
    // Constructors
    Collator_Unicode();
    // Destructor
    ~Collator_Unicode();

    sal_Int32 SAL_CALL compareSubstring( const rtl::OUString& s1, sal_Int32 off1, sal_Int32 len1,
        const rtl::OUString& s2, sal_Int32 off2, sal_Int32 len2) throw(com::sun::star::uno::RuntimeException);

    sal_Int32 SAL_CALL compareString( const rtl::OUString& s1, const rtl::OUString& s2)
        throw(com::sun::star::uno::RuntimeException);

    sal_Int32 SAL_CALL loadCollatorAlgorithm( const rtl::OUString& impl, const lang::Locale& rLocale,
        sal_Int32 collatorOptions) throw(com::sun::star::uno::RuntimeException);

    // following 4 methods are implemented in collatorImpl.
    sal_Int32 SAL_CALL loadDefaultCollator( const lang::Locale&,  sal_Int32)
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    void SAL_CALL loadCollatorAlgorithmWithEndUserOption( const rtl::OUString&, const lang::Locale&,
        const com::sun::star::uno::Sequence< sal_Int32 >&) throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL listCollatorAlgorithms( const lang::Locale&)
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL listCollatorOptions( const rtl::OUString& )
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName() throw( com::sun::star::uno::RuntimeException );
    virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw( com::sun::star::uno::RuntimeException );

protected:
    const sal_Char *implementationName;
private:
    RuleBasedCollator *collator;
    oslModule hModule;
};

} } } }

#endif
<commit_msg>INTEGRATION: CWS i18n39 (1.11.78); FILE MERGED 2008/01/11 07:39:15 khong 1.11.78.1: i78055 provide UCA as base for ICU collator constructor from image rule<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: collator_unicode.hxx,v $
 *
 *  $Revision: 1.12 $
 *
 *  last change: $Author: vg $ $Date: 2008-01-28 15:33:02 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/
#ifndef _I18N_COLLATOR_UNICODE_HXX_
#define _I18N_COLLATOR_UNICODE_HXX_

#include <com/sun/star/uno/Reference.h>
#include <com/sun/star/i18n/XCollator.hpp>
#include <cppuhelper/implbase1.hxx>
#include <osl/module.h>

#include "warnings_guard_unicode_tblcoll.h"

//      ----------------------------------------------------
//      class Collator_Unicode
//      ----------------------------------------------------

namespace com { namespace sun { namespace star { namespace i18n {

class Collator_Unicode : public cppu::WeakImplHelper1 < XCollator >
{
public:
    // Constructors
    Collator_Unicode();
    // Destructor
    ~Collator_Unicode();

    sal_Int32 SAL_CALL compareSubstring( const rtl::OUString& s1, sal_Int32 off1, sal_Int32 len1,
        const rtl::OUString& s2, sal_Int32 off2, sal_Int32 len2) throw(com::sun::star::uno::RuntimeException);

    sal_Int32 SAL_CALL compareString( const rtl::OUString& s1, const rtl::OUString& s2)
        throw(com::sun::star::uno::RuntimeException);

    sal_Int32 SAL_CALL loadCollatorAlgorithm( const rtl::OUString& impl, const lang::Locale& rLocale,
        sal_Int32 collatorOptions) throw(com::sun::star::uno::RuntimeException);

    // following 4 methods are implemented in collatorImpl.
    sal_Int32 SAL_CALL loadDefaultCollator( const lang::Locale&,  sal_Int32)
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    void SAL_CALL loadCollatorAlgorithmWithEndUserOption( const rtl::OUString&, const lang::Locale&,
        const com::sun::star::uno::Sequence< sal_Int32 >&) throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL listCollatorAlgorithms( const lang::Locale&)
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}
    com::sun::star::uno::Sequence< sal_Int32 > SAL_CALL listCollatorOptions( const rtl::OUString& )
        throw(com::sun::star::uno::RuntimeException) {throw com::sun::star::uno::RuntimeException();}

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName() throw( com::sun::star::uno::RuntimeException );
    virtual sal_Bool SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( com::sun::star::uno::RuntimeException );
    virtual com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw( com::sun::star::uno::RuntimeException );

protected:
    const sal_Char *implementationName;
private:
    RuleBasedCollator *uca_base, *collator;
    oslModule hModule;
};

} } } }

#endif
<|endoftext|>


<commit_before>// Copyright 2013 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 "android_webview/native/skia_java_output_stream.h"

#include "base/logging.h"

// Disable "Warnings treated as errors" for input_stream_jni as it's a Java
// system class and we have to generate C++ hooks for all methods in the class
// even if they're unused.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include "jni/OutputStream_jni.h"
#include "jni/CancellationSignal_jni.h"
#pragma GCC diagnostic pop
using base::android::ClearException;
using base::android::JavaRef;
using JNI_OutputStream::Java_OutputStream_writeV_AB_I_I;
using JNI_OutputStream::Java_OutputStream_flush;
using JNI_CancellationSignal::Java_CancellationSignal_isCanceled;

namespace android_webview {

const size_t SkiaJavaOutputStream::kBufferSize = 4096;

SkiaJavaOutputStream::SkiaJavaOutputStream(
    JNIEnv* env,
    const JavaRef<jobject>& stream,
    const JavaRef<jobject>& cancel_signal)
    : env_(env),
      stream_(stream),
      cancel_signal_(cancel_signal) {
}

SkiaJavaOutputStream::~SkiaJavaOutputStream() { }

// TODO(sgurun) make sure shutdown while writing/flush is handled properly
// potentially via a cancel API in webview.
bool SkiaJavaOutputStream::write(const void* buffer, size_t size) {
  if (!buffer_.obj()) {
    // Allocate transfer buffer.
    base::android::ScopedJavaLocalRef<jbyteArray> temp(
        env_, env_->NewByteArray(kBufferSize));
    buffer_.Reset(temp);
    if (ClearException(env_))
      return false;
  }
  const jbyte* bufptr = reinterpret_cast<const jbyte*>(buffer);
  while (size > 0) {
    if (cancel_signal_.obj() != NULL &&
        Java_CancellationSignal_isCanceled(env_, cancel_signal_.obj())) {
      return false;
    }
    size_t requested = size;
    if (requested > kBufferSize) {
      requested = kBufferSize;
    }

    env_->SetByteArrayRegion(buffer_.obj(), 0, requested, bufptr);
    if (ClearException(env_)) {
      LOG(WARNING) << "write:SetByteArrayRegion threw an exception";
      return false;
    }

    Java_OutputStream_writeV_AB_I_I(
        env_, stream_.obj(), buffer_.obj(), 0, requested);
    if (ClearException(env_)) {
      LOG(WARNING) << "write:write threw an exception";
      return false;
    }
    bufptr += requested;
    size -= requested;
  }

  return true;
}

void SkiaJavaOutputStream::flush() {
  Java_OutputStream_flush(env_, stream_.obj());
  if (ClearException(env_)) {
      LOG(WARNING) << "flush threw an exception";
  }
}

bool RegisterSkiaJavaOutputStream(JNIEnv* env) {
  return JNI_OutputStream::RegisterNativesImpl(env) &&
      JNI_CancellationSignal::RegisterNativesImpl(env);
}

}  // namespace android_webview
<commit_msg>Fix crash due to a null pointer.<commit_after>// Copyright 2013 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 "android_webview/native/skia_java_output_stream.h"

#include "base/logging.h"

// Disable "Warnings treated as errors" for input_stream_jni as it's a Java
// system class and we have to generate C++ hooks for all methods in the class
// even if they're unused.
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-function"
#include "jni/OutputStream_jni.h"
#include "jni/CancellationSignal_jni.h"
#pragma GCC diagnostic pop
using base::android::ClearException;
using base::android::JavaRef;
using JNI_OutputStream::Java_OutputStream_writeV_AB_I_I;
using JNI_OutputStream::Java_OutputStream_flush;
using JNI_CancellationSignal::Java_CancellationSignal_isCanceled;

namespace android_webview {

const size_t SkiaJavaOutputStream::kBufferSize = 4096;

SkiaJavaOutputStream::SkiaJavaOutputStream(
    JNIEnv* env,
    const JavaRef<jobject>& stream,
    const JavaRef<jobject>& cancel_signal)
    : env_(env),
      stream_(stream),
      cancel_signal_(cancel_signal) {
}

SkiaJavaOutputStream::~SkiaJavaOutputStream() { }

bool SkiaJavaOutputStream::write(const void* buffer, size_t size) {

  if (buffer == NULL) {
    LOG(WARNING) << "write: buffer pointer is NULL";
    return false;
  }

  if (!buffer_.obj()) {
    // Allocate transfer buffer.
    base::android::ScopedJavaLocalRef<jbyteArray> temp(
        env_, env_->NewByteArray(kBufferSize));
    buffer_.Reset(temp);
    if (ClearException(env_))
      return false;
  }
  const jbyte* bufptr = reinterpret_cast<const jbyte*>(buffer);
  while (size > 0) {
    if (cancel_signal_.obj() != NULL &&
        Java_CancellationSignal_isCanceled(env_, cancel_signal_.obj())) {
      return false;
    }
    size_t requested = size;
    if (requested > kBufferSize) {
      requested = kBufferSize;
    }

    env_->SetByteArrayRegion(buffer_.obj(), 0, requested, bufptr);
    if (ClearException(env_)) {
      LOG(WARNING) << "write:SetByteArrayRegion threw an exception";
      return false;
    }

    Java_OutputStream_writeV_AB_I_I(
        env_, stream_.obj(), buffer_.obj(), 0, requested);
    if (ClearException(env_)) {
      LOG(WARNING) << "write:write threw an exception";
      return false;
    }
    bufptr += requested;
    size -= requested;
  }

  return true;
}

void SkiaJavaOutputStream::flush() {
  Java_OutputStream_flush(env_, stream_.obj());
  if (ClearException(env_)) {
      LOG(WARNING) << "flush threw an exception";
  }
}

bool RegisterSkiaJavaOutputStream(JNIEnv* env) {
  return JNI_OutputStream::RegisterNativesImpl(env) &&
      JNI_CancellationSignal::RegisterNativesImpl(env);
}

}  // namespace android_webview
<|endoftext|>


<commit_before>#include <pcl/point_cloud.h>
#include <pcl_ros/point_cloud.h>
#include <ros/publisher.h>
#include <ros/ros.h>
#include <stdlib.h>
#include <Eigen/Core>
#include <opencv2/opencv.hpp>

ros::Publisher pointcloud_pub;
cv::Mat published_map; // get to work
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> global_map;
double resolution;
double position [2] = {0, 0};
int length;
int width;

void frame_callback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &msg, const std::string &topic)
{
  //transform pointcloud into the occupancy grid, no filtering right now
  bool offMap = false;
  //for(pcl::PointXYZRGB point : msg) // how to iterate through all points??
  //cv::Mat frame(msg->points);
  pcl::PointCloud<pcl::PointXYZ>::const_iterator point;
  for (point = msg->points.begin(); point < msg->points.end(); point++)
  {
    //assuming is meters from robot origin
    //transform coordinates
    double x = point->x / resolution;
    double y = point->y / resolution;

    x += position[0];
    y += position[1];
    if(x > 0 && y > 0 && x < length && y < width)
    {
      global_map(x, y) = 1.0;
    } else if(!offMap){
      ROS_WARN_STREAM("Some points out of range, won't be put on map.");
      offMap = true;
    }
  }

  pointcloud_pub.publish(published_map);
}

int main(int argc, char **argv)
{

  ros::init(argc, argv, "new_mapper");
  ros::NodeHandle nh;

  std::string topics;
  std::list<ros::Subscriber> subs;

  ros::NodeHandle pNh("~");

  double start_x;
  double start_y;

  pNh.getParam("topics", topics);
  pNh.getParam("occupancy_grid_length", length);
  pNh.getParam("occupancy_grid_width", width);
  pNh.getParam("qoccupancy_grid_resolution", resolution);
  pNh.getParam("start_X", start_x);
  pNh.getParam("start_Y", start_y);

  length = (int) (length / resolution);
  width = (int) (width / resolution);
  position[0] = start_x / resolution;
  position[1] = start_y / resolution;
  //global_map = Eigen::Matrix<float, Dynamic, Dynamic>(length, width);

  published_map(length, width, 2.0, cv::Scalar(0,0,0)); // I cant instatiate this
  //https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
  global_map(published_map.data()); // i can't instantiate this either
  //https://stackoverflow.com/questions/14783329/opencv-cvmat-and-eigenmatrix

  //will need to change when subscribe to multiple topics
  std::list<std::string> tokens = {topics};
  for (std:: string t : tokens)
  {
    ROS_INFO_STREAM("Mapper subscribing to " << t);
    subs.push_back(nh.subscribe<pcl::PointCloud<pcl::PointXYZ>>(t, 1,boost::bind(frame_callback, _1, t)));
  }
  pointcloud_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB>>("/map", 1);

  ros::spin();
}
<commit_msg>Not much is working, have a basic framework<commit_after>#include <pcl/point_cloud.h>
#include <pcl_ros/point_cloud.h>
#include <ros/publisher.h>
#include <ros/ros.h>
#include <stdlib.h>
#include <Eigen/Core>
#include <opencv2/opencv.hpp>

ros::Publisher pointcloud_pub;
cv::Mat published_map; // get to work
Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic> global_map;
tf::StampedTransform lidar_trans;
tf::StampedTransform cam_trans;

double resolution;
double position [2] = {0, 0};
int length;
int width;

void frame_callback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr &msg, const std::string &topic)
{
  //transform pointcloud into the occupancy grid, no filtering right now
  bool offMap = false;
  //for(pcl::PointXYZRGB point : msg) // how to iterate through all points??
  //cv::Mat frame(msg->points);
  pcl::PointCloud<pcl::PointXYZ>::const_iterator point;
  for (point = msg->points.begin(); point < msg->points.end(); point++)
  {
    //assuming is meters from robot origin
    //transform coordinates
    double x = point->x / resolution;
    double y = point->y / resolution;

    x += position[0];
    y += position[1];
    if(x > 0 && y > 0 && x < length && y < width)
    {
      global_map(x, y) = 1.0;
    } else if(!offMap){
      ROS_WARN_STREAM("Some points out of range, won't be put on map.");
      offMap = true;
    }
  }

  pointcloud_pub.publish(published_map);
}

int main(int argc, char **argv)
{

  ros::init(argc, argv, "new_mapper");
  ros::NodeHandle nh;

  std::string topics;
  std::list<ros::Subscriber> subs;

  ros::NodeHandle pNh("~");

   tf_listener = new tf::TransformListener();

  double start_x;
  double start_y;

  pNh.getParam("topics", topics);
  pNh.getParam("occupancy_grid_length", length);
  pNh.getParam("occupancy_grid_width", width);
  pNh.getParam("qoccupancy_grid_resolution", resolution);
  pNh.getParam("start_X", start_x);
  pNh.getParam("start_Y", start_y);

  length = (int) (length / resolution);
  width = (int) (width / resolution);
  position[0] = start_x / resolution;
  position[1] = start_y / resolution;
  //global_map = Eigen::Matrix<float, Dynamic, Dynamic>(length, width);

  published_map(length, width, CV_32FC1, const cv::Scalar(0,0,0)); // I cant instatiate this
  //https://docs.opencv.org/2.4/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
  global_map(published_map.data()); // I can't instantiate this either
  //https://stackoverflow.com/questions/14783329/opencv-cvmat-and-eigenmatrix

  //will need to change when subscribe to multiple topics
  std::list<std::string> tokens = {topics};
  for (std:: string t : tokens)
  {
    ROS_INFO_STREAM("Mapper subscribing to " << t);
    subs.push_back(nh.subscribe<pcl::PointCloud<pcl::PointXYZ>>(t, 1,boost::bind(frame_callback, _1, t)));
  }
  pointcloud_pub = nh.advertise<pcl::PointCloud<pcl::PointXYZRGB>>("/map", 1);

  ros::spin();
}
<|endoftext|>


<commit_before>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// 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.

#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED
#define LUABIND_CALL_FUNCTION_HPP_INCLUDED

#include <luabind/config.hpp>

#include <luabind/error.hpp>
#include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/pcall.hpp>
#include <luabind/detail/call_shared.hpp>
#include <luabind/detail/stack_utils.hpp>

namespace luabind
{
	namespace adl {
		class object;
	}

	using adl::object;

	namespace detail {

		template< typename PolicyList, unsigned int pos >
        void push_arguments(lua_State* /*L*/) {};

		template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args >
		void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args)
		{
			using converter_type = specialized_converter_policy< fetched_converter_policy<Pos, PolicyList>, Arg0, cpp_to_lua >;
			converter_type().to_lua(L, unwrapped<Arg0>::get(std::forward<Arg0>(arg0)));
			push_arguments<PolicyList, Pos+1>(L, std::forward<Args>(args)...);
		}

#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
		void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list<Indices...>, Args&&... args)
		{
			int top = lua_gettop(L);

			push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

			if (fn(L, sizeof...(Args), 0)) {
				assert(lua_gettop(L) == top - m_params + 1);
				call_error(L);
			}
			// pops the return values from the function call
			stack_pop pop(L, lua_gettop(L) - top + m_params);
		}

		template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
		Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */ , meta::index_list<Indices...>, Args&&... args)
		{
			int top = lua_gettop(L);

			push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

			if (fn(L, sizeof...(Args), 1)) {
				assert(lua_gettop(L) == top - m_params + 1);
				call_error(L);
			}
			// pops the return values from the function call
			stack_pop pop(L, lua_gettop(L) - top + m_params);

			specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
			if (converter.match(L, decorated_type<Ret>(), -1) < 0) {
				cast_error<Ret>(L);
			}

			return converter.to_cpp(L, decorated_type<Ret>(), -1);
		}
#else
		template<typename Ret, typename PolicyList, typename IndexList, unsigned int NumParams, int(*Function)(lua_State*, int, int), bool IsVoid = std::is_void<Ret>::value>
		struct call_function_struct;

		template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
		struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, true /* void */ >
		{
			template< typename... Args >
			static void call(lua_State* L, Args&&... args) {
				int top = lua_gettop(L);

				push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

				if(Function(L, sizeof...(Args), 0)) {
					assert(lua_gettop(L)==top-NumParams+1);
					call_error(L);
				}
				// pops the return values from the function call
				stack_pop pop(L, lua_gettop(L)-top+NumParams);
			}
		};

		template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
		struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, false /* void */ >
		{
			template< typename... Args >
			static Ret call(lua_State* L, Args&&... args) {
				int top = lua_gettop(L);

				push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

				if(Function(L, sizeof...(Args), 1)) {
					assert(lua_gettop(L)==top-NumParams+1);
					call_error(L);
				}
				// pops the return values from the function call
				stack_pop pop(L, lua_gettop(L)-top+NumParams);

				specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
				if(converter.match(L, decorated_type<Ret>(), -1)<0) {
					cast_error<Ret>(L);
				}

				return converter.to_cpp(L, decorated_type<Ret>(), -1);
			}
		};
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R call_pushed_function(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 1, &detail::pcall, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::pcall >::call(L, std::forward<Args>(args)...);
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R call_function(lua_State* L, const char* name, Args&&... args )
	{
		assert(name && "luabind::call_function() expects a function name");
		lua_getglobal(L, name);
		return call_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume_pushed_function(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 1, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume_function(lua_State* L, const char* name, Args&&... args)
	{
		assert(name && "luabind::resume_function() expects a function name");
		lua_getglobal(L, name);
		return resume_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 0, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 0, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
#endif
	}

}

#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED

<commit_msg>Fix signed/unsigned mismatch warning.<commit_after>// Copyright (c) 2003 Daniel Wallin and Arvid Norberg

// 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.

#ifndef LUABIND_CALL_FUNCTION_HPP_INCLUDED
#define LUABIND_CALL_FUNCTION_HPP_INCLUDED

#include <luabind/config.hpp>

#include <luabind/error.hpp>
#include <luabind/detail/convert_to_lua.hpp>
#include <luabind/detail/pcall.hpp>
#include <luabind/detail/call_shared.hpp>
#include <luabind/detail/stack_utils.hpp>

namespace luabind
{
	namespace adl {
		class object;
	}

	using adl::object;

	namespace detail {

		template< typename PolicyList, unsigned int pos >
        void push_arguments(lua_State* /*L*/) {};

		template< typename PolicyList, unsigned int Pos, typename Arg0, typename... Args >
		void push_arguments(lua_State* L, Arg0&& arg0, Args&&... args)
		{
			using converter_type = specialized_converter_policy< fetched_converter_policy<Pos, PolicyList>, Arg0, cpp_to_lua >;
			converter_type().to_lua(L, unwrapped<Arg0>::get(std::forward<Arg0>(arg0)));
			push_arguments<PolicyList, Pos+1>(L, std::forward<Args>(args)...);
		}

#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
		void call_function_impl(lua_State* L, int m_params, Fn fn, std::true_type /* void */, meta::index_list<Indices...>, Args&&... args)
		{
			int top = lua_gettop(L);

			push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

			if (fn(L, sizeof...(Args), 0)) {
				assert(lua_gettop(L) == top - m_params + 1);
				call_error(L);
			}
			// pops the return values from the function call
			stack_pop pop(L, lua_gettop(L) - top + m_params);
		}

		template<typename Ret, typename PolicyList, typename... Args, unsigned int... Indices, typename Fn>
		Ret call_function_impl(lua_State* L, int m_params, Fn fn, std::false_type /* void */ , meta::index_list<Indices...>, Args&&... args)
		{
			int top = lua_gettop(L);

			push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

			if (fn(L, sizeof...(Args), 1)) {
				assert(lua_gettop(L) == top - m_params + 1);
				call_error(L);
			}
			// pops the return values from the function call
			stack_pop pop(L, lua_gettop(L) - top + m_params);

			specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
			if (converter.match(L, decorated_type<Ret>(), -1) < 0) {
				cast_error<Ret>(L);
			}

			return converter.to_cpp(L, decorated_type<Ret>(), -1);
		}
#else
		template<typename Ret, typename PolicyList, typename IndexList, unsigned int NumParams, int(*Function)(lua_State*, int, int), bool IsVoid = std::is_void<Ret>::value>
		struct call_function_struct;

		template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
		struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, true /* void */ >
		{
			template< typename... Args >
			static void call(lua_State* L, Args&&... args) {
				int top = lua_gettop(L);

				push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

				if(Function(L, sizeof...(Args), 0)) {
					assert(lua_gettop(L)==int(top-NumParams+1));
					call_error(L);
				}
				// pops the return values from the function call
				stack_pop pop(L, lua_gettop(L)-top+NumParams);
			}
		};

		template<typename Ret, typename PolicyList, unsigned int NumParams, int(*Function)(lua_State*, int, int), unsigned int... Indices >
		struct call_function_struct< Ret, PolicyList, meta::index_list<Indices...>, NumParams, Function, false /* void */ >
		{
			template< typename... Args >
			static Ret call(lua_State* L, Args&&... args) {
				int top = lua_gettop(L);

				push_arguments<PolicyList, 1>(L, std::forward<Args>(args)...);

				if(Function(L, sizeof...(Args), 1)) {
					assert(lua_gettop(L)==top-NumParams+1);
					call_error(L);
				}
				// pops the return values from the function call
				stack_pop pop(L, lua_gettop(L)-top+NumParams);

				specialized_converter_policy_n<0, PolicyList, Ret, lua_to_cpp> converter;
				if(converter.match(L, decorated_type<Ret>(), -1)<0) {
					cast_error<Ret>(L);
				}

				return converter.to_cpp(L, decorated_type<Ret>(), -1);
			}
		};
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R call_pushed_function(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 1, &detail::pcall, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::pcall >::call(L, std::forward<Args>(args)...);
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R call_function(lua_State* L, const char* name, Args&&... args )
	{
		assert(name && "luabind::call_function() expects a function name");
		lua_getglobal(L, name);
		return call_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume_pushed_function(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 1, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 1, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
#endif
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume_function(lua_State* L, const char* name, Args&&... args)
	{
		assert(name && "luabind::resume_function() expects a function name");
		lua_getglobal(L, name);
		return resume_pushed_function<R, PolicyList>(L, std::forward<Args>(args)...);
	}

	template<class R, typename PolicyList = no_policies, typename... Args>
	R resume(lua_State* L, Args&&... args)
	{
#ifndef LUABIND_NO_INTERNAL_TAG_ARGUMENTS
		return detail::call_function_impl<R, PolicyList>(L, 0, &detail::resume_impl, std::is_void<R>(), meta::index_range<1, sizeof...(Args) +1>(), std::forward<Args>(args)...);
#else
		return detail::call_function_struct<R, PolicyList, meta::index_range<1, sizeof...(Args)+1>, 0, &detail::resume_impl >::call(L, std::forward<Args>(args)...);
#endif
	}

}

#endif // LUABIND_CALL_FUNCTION_HPP_INCLUDED

<|endoftext|>


<commit_before>//===- Support/FileUtilities.cpp - File System Utilities ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a family of utility functions which are useful for doing
// various things with files.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Config/unistd.h"
#include "llvm/Config/fcntl.h"
#include "llvm/Config/sys/types.h"
#include "llvm/Config/sys/stat.h"
#include "llvm/Config/sys/mman.h"
#include "llvm/Config/alloca.h"
#include <cerrno>
#include <cstdio>
#include <fstream>
#include <iostream>
using namespace llvm;

/// CheckMagic - Returns true IFF the file named FN begins with Magic. FN must
/// name a readable file.
///
bool llvm::CheckMagic(const std::string &FN, const std::string &Magic) {
  char *buf = (char*)alloca(1 + Magic.size());
  std::ifstream f(FN.c_str());
  f.read(buf, Magic.size());
  buf[Magic.size()] = '\0';
  return Magic == buf;
}

/// IsArchive - Returns true IFF the file named FN appears to be a "ar" library
/// archive. The file named FN must exist.
///
bool llvm::IsArchive(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the "ar"
  // library archive format magic string.
  return CheckMagic(FN, "!<arch>\012");
}

/// IsBytecode - Returns true IFF the file named FN appears to be an LLVM
/// bytecode file. The file named FN must exist.
///
bool llvm::IsBytecode(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the LLVM
  // bytecode format magic string.
  return CheckMagic (FN, "llvm");
}

/// IsSharedObject - Returns trus IFF the file named FN appears to be a shared
/// object with an ELF header. The file named FN must exist.
///
bool llvm::IsSharedObject(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the ELF shared
  // object magic string.
  static const char elfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
  return CheckMagic(FN, elfMagic);
}

/// FileOpenable - Returns true IFF Filename names an existing regular
/// file which we can successfully open.
///
bool llvm::FileOpenable(const std::string &Filename) {
  struct stat s;
  if (stat (Filename.c_str (), &s) == -1)
    return false; // Cannot stat file
  if (!S_ISREG (s.st_mode))
    return false; // File is not a regular file
  std::ifstream FileStream (Filename.c_str ());
  if (!FileStream)
    return false; // File is not openable
  return true;
}

/// DiffFiles - Compare the two files specified, returning true if they are
/// different or if there is a file error.  If you specify a string to fill in
/// for the error option, it will set the string to an error message if an error
/// occurs, allowing the caller to distinguish between a failed diff and a file
/// system error.
///
bool llvm::DiffFiles(const std::string &FileA, const std::string &FileB,
                     std::string *Error) {
  std::ifstream FileAStream(FileA.c_str());
  if (!FileAStream) {
    if (Error) *Error = "Couldn't open file '" + FileA + "'";
    return true;
  }

  std::ifstream FileBStream(FileB.c_str());
  if (!FileBStream) {
    if (Error) *Error = "Couldn't open file '" + FileB + "'";
    return true;
  }

  // Compare the two files...
  int C1, C2;
  do {
    C1 = FileAStream.get();
    C2 = FileBStream.get();
    if (C1 != C2) return true;
  } while (C1 != EOF);

  return false;
}

/// CopyFile - Copy the specified source file to the specified destination,
/// overwriting destination if it exists.  This returns true on failure.
///
bool llvm::CopyFile(const std::string &Dest, const std::string &Src) {
  FDHandle InFD(open(Src.c_str(), O_RDONLY));
  if (InFD == -1) return true;

  FileRemover FR(Dest);

  FDHandle OutFD(open(Dest.c_str(), O_WRONLY|O_CREAT, 0666));
  if (OutFD == -1) return true;

  char Buffer[16*1024];
  while (ssize_t Amt = read(InFD, Buffer, 16*1024)) {
    if (Amt == -1) {
      if (errno != EINTR) return true;  // Error reading the file.
    } else {
      char *BufPtr = Buffer;
      while (Amt) {
        ssize_t AmtWritten = write(OutFD, BufPtr, Amt);
        if (AmtWritten == -1) {
          if (errno != EINTR) return true;  // Error writing the file.
        } else {
          Amt -= AmtWritten;
          BufPtr += AmtWritten;
        }
      }
    }
  }

  FR.releaseFile();  // Success!
  return false;
}

/// MoveFileOverIfUpdated - If the file specified by New is different than Old,
/// or if Old does not exist, move the New file over the Old file.  Otherwise,
/// remove the New file.
///
void llvm::MoveFileOverIfUpdated(const std::string &New,
                                 const std::string &Old) {
  if (DiffFiles(New, Old)) {
    if (std::rename(New.c_str(), Old.c_str()))
      std::cerr << "Error renaming '" << New << "' to '" << Old << "'!\n";
  } else {
    std::remove(New.c_str());
  }
}

/// removeFile - Delete the specified file
///
void llvm::removeFile(const std::string &Filename) {
  std::remove(Filename.c_str());
}

/// getUniqueFilename - Return a filename with the specified prefix.  If the
/// file does not exist yet, return it, otherwise add a suffix to make it
/// unique.
///
std::string llvm::getUniqueFilename(const std::string &FilenameBase) {
  if (!std::ifstream(FilenameBase.c_str()))
    return FilenameBase;    // Couldn't open the file? Use it!

  // Create a pattern for mkstemp...
  char *FNBuffer = new char[FilenameBase.size()+8];
  strcpy(FNBuffer, FilenameBase.c_str());
  strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX");

  // Agree on a temporary file name to use....
#if defined(HAVE_MKSTEMP) && !defined(_MSC_VER)
  int TempFD;
  if ((TempFD = mkstemp(FNBuffer)) == -1) {
    // FIXME: this should return an emtpy string or something and allow the
    // caller to deal with the error!
    std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current "
	      << " directory!\n";
    exit(1);
  }

  // We don't need to hold the temp file descriptor... we will trust that no one
  // will overwrite/delete the file while we are working on it...
  close(TempFD);
#else
  // If we don't have mkstemp, use the old and obsolete mktemp function.
  if (mktemp(FNBuffer) == 0) {
    // FIXME: this should return an emtpy string or something and allow the
    // caller to deal with the error!
    std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current "
              << " directory!\n";
    exit(1);
  }
#endif

  std::string Result(FNBuffer);
  delete[] FNBuffer;
  return Result;
}

static bool AddPermissionsBits (const std::string &Filename, int bits) {
  // Get the umask value from the operating system.  We want to use it
  // when changing the file's permissions. Since calling umask() sets
  // the umask and returns its old value, we must call it a second
  // time to reset it to the user's preference.
  int mask = umask(0777); // The arg. to umask is arbitrary.
  umask(mask);            // Restore the umask.

  // Get the file's current mode.
  struct stat st;
  if ((stat(Filename.c_str(), &st)) == -1)
    return false;

  // Change the file to have whichever permissions bits from 'bits'
  // that the umask would not disable.
  if ((chmod(Filename.c_str(), (st.st_mode | (bits & ~mask)))) == -1)
    return false;

  return true;
}

/// MakeFileExecutable - Make the file named Filename executable by
/// setting whichever execute permissions bits the process's current
/// umask would allow. Filename must name an existing file or
/// directory.  Returns true on success, false on error.
///
bool llvm::MakeFileExecutable(const std::string &Filename) {
  return AddPermissionsBits(Filename, 0111);
}

/// MakeFileReadable - Make the file named Filename readable by
/// setting whichever read permissions bits the process's current
/// umask would allow. Filename must name an existing file or
/// directory.  Returns true on success, false on error.
///
bool llvm::MakeFileReadable(const std::string &Filename) {
  return AddPermissionsBits(Filename, 0444);
}

/// getFileSize - Return the size of the specified file in bytes, or -1 if the
/// file cannot be read or does not exist.
long long llvm::getFileSize(const std::string &Filename) {
  struct stat StatBuf;
  if (stat(Filename.c_str(), &StatBuf) == -1)
    return -1;
  return StatBuf.st_size;
}

/// getFileTimestamp - Get the last modified time for the specified file in an
/// unspecified format.  This is useful to allow checking to see if a file was
/// updated since that last time the timestampt was aquired.  If the file does
/// not exist or there is an error getting the time-stamp, zero is returned.
unsigned long long llvm::getFileTimestamp(const std::string &Filename) {
  struct stat StatBuf;
  if (stat(Filename.c_str(), &StatBuf) == -1)
    return 0;
  return StatBuf.st_mtime;
}

/// ReadFileIntoAddressSpace - Attempt to map the specific file into the
/// address space of the current process for reading.  If this succeeds,
/// return the address of the buffer and the length of the file mapped.  On
/// failure, return null.
void *llvm::ReadFileIntoAddressSpace(const std::string &Filename,
                                     unsigned &Length) {
#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER)
  Length = (unsigned)getFileSize(Filename);
  if ((int)Length == -1) return 0;

  FDHandle FD(open(Filename.c_str(), O_RDONLY));
  if (FD == -1) return 0;

  // If the file has a length of zero, mmap might return a null pointer.  In
  // this case, allocate a single byte of memory and return it instead.
  if (Length == 0)
    return malloc(1);

  // mmap in the file all at once...
  void *Buffer = (void*)mmap(0, Length, PROT_READ, MAP_PRIVATE, FD, 0);

  if (Buffer == (void*)MAP_FAILED)
    return 0;

  return Buffer;
#else
  // FIXME: implement with read/write
#error Unimplemented ReadFileIntoAddressSpace - need to use read/write.
  return 0;
#endif
}

/// UnmapFileFromAddressSpace - Remove the specified file from the current
/// address space.
void llvm::UnmapFileFromAddressSpace(void *Buffer, unsigned Length) {
#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER)
  if (Length)
    munmap((char*)Buffer, Length);
  else
    free(Buffer);  // Zero byte files are malloc(1)'s.
#else
  free(Buffer);
#endif
}

//===----------------------------------------------------------------------===//
// FDHandle class implementation
//

FDHandle::~FDHandle() throw() {
  if (FD != -1) close(FD);
}

FDHandle &FDHandle::operator=(int fd) throw() {
  if (FD != -1) close(FD);
  FD = fd;
  return *this;
}

<commit_msg>Handle headers for compressed bytecode files<commit_after>//===- Support/FileUtilities.cpp - File System Utilities ------------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements a family of utility functions which are useful for doing
// various things with files.
//
//===----------------------------------------------------------------------===//

#include "llvm/Support/FileUtilities.h"
#include "llvm/Support/DataTypes.h"
#include "llvm/Config/unistd.h"
#include "llvm/Config/fcntl.h"
#include "llvm/Config/sys/types.h"
#include "llvm/Config/sys/stat.h"
#include "llvm/Config/sys/mman.h"
#include "llvm/Config/alloca.h"
#include <cerrno>
#include <cstdio>
#include <fstream>
#include <iostream>
using namespace llvm;

/// CheckMagic - Returns true IFF the file named FN begins with Magic. FN must
/// name a readable file.
///
bool llvm::CheckMagic(const std::string &FN, const std::string &Magic) {
  char *buf = (char*)alloca(1 + Magic.size());
  std::ifstream f(FN.c_str());
  f.read(buf, Magic.size());
  buf[Magic.size()] = '\0';
  return Magic == buf;
}

/// IsArchive - Returns true IFF the file named FN appears to be a "ar" library
/// archive. The file named FN must exist.
///
bool llvm::IsArchive(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the "ar"
  // library archive format magic string.
  return CheckMagic(FN, "!<arch>\012");
}

/// IsBytecode - Returns true IFF the file named FN appears to be an LLVM
/// bytecode file. The file named FN must exist.
///
bool llvm::IsBytecode(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the LLVM
  // bytecode format magic string.
  return CheckMagic(FN, "llvm") || CheckMagic(FN, "llvc");
}

/// IsSharedObject - Returns trus IFF the file named FN appears to be a shared
/// object with an ELF header. The file named FN must exist.
///
bool llvm::IsSharedObject(const std::string &FN) {
  // Inspect the beginning of the file to see if it contains the ELF shared
  // object magic string.
  static const char elfMagic[] = { 0x7f, 'E', 'L', 'F', '\0' };
  return CheckMagic(FN, elfMagic);
}

/// FileOpenable - Returns true IFF Filename names an existing regular
/// file which we can successfully open.
///
bool llvm::FileOpenable(const std::string &Filename) {
  struct stat s;
  if (stat (Filename.c_str (), &s) == -1)
    return false; // Cannot stat file
  if (!S_ISREG (s.st_mode))
    return false; // File is not a regular file
  std::ifstream FileStream (Filename.c_str ());
  if (!FileStream)
    return false; // File is not openable
  return true;
}

/// DiffFiles - Compare the two files specified, returning true if they are
/// different or if there is a file error.  If you specify a string to fill in
/// for the error option, it will set the string to an error message if an error
/// occurs, allowing the caller to distinguish between a failed diff and a file
/// system error.
///
bool llvm::DiffFiles(const std::string &FileA, const std::string &FileB,
                     std::string *Error) {
  std::ifstream FileAStream(FileA.c_str());
  if (!FileAStream) {
    if (Error) *Error = "Couldn't open file '" + FileA + "'";
    return true;
  }

  std::ifstream FileBStream(FileB.c_str());
  if (!FileBStream) {
    if (Error) *Error = "Couldn't open file '" + FileB + "'";
    return true;
  }

  // Compare the two files...
  int C1, C2;
  do {
    C1 = FileAStream.get();
    C2 = FileBStream.get();
    if (C1 != C2) return true;
  } while (C1 != EOF);

  return false;
}

/// CopyFile - Copy the specified source file to the specified destination,
/// overwriting destination if it exists.  This returns true on failure.
///
bool llvm::CopyFile(const std::string &Dest, const std::string &Src) {
  FDHandle InFD(open(Src.c_str(), O_RDONLY));
  if (InFD == -1) return true;

  FileRemover FR(Dest);

  FDHandle OutFD(open(Dest.c_str(), O_WRONLY|O_CREAT, 0666));
  if (OutFD == -1) return true;

  char Buffer[16*1024];
  while (ssize_t Amt = read(InFD, Buffer, 16*1024)) {
    if (Amt == -1) {
      if (errno != EINTR) return true;  // Error reading the file.
    } else {
      char *BufPtr = Buffer;
      while (Amt) {
        ssize_t AmtWritten = write(OutFD, BufPtr, Amt);
        if (AmtWritten == -1) {
          if (errno != EINTR) return true;  // Error writing the file.
        } else {
          Amt -= AmtWritten;
          BufPtr += AmtWritten;
        }
      }
    }
  }

  FR.releaseFile();  // Success!
  return false;
}

/// MoveFileOverIfUpdated - If the file specified by New is different than Old,
/// or if Old does not exist, move the New file over the Old file.  Otherwise,
/// remove the New file.
///
void llvm::MoveFileOverIfUpdated(const std::string &New,
                                 const std::string &Old) {
  if (DiffFiles(New, Old)) {
    if (std::rename(New.c_str(), Old.c_str()))
      std::cerr << "Error renaming '" << New << "' to '" << Old << "'!\n";
  } else {
    std::remove(New.c_str());
  }
}

/// removeFile - Delete the specified file
///
void llvm::removeFile(const std::string &Filename) {
  std::remove(Filename.c_str());
}

/// getUniqueFilename - Return a filename with the specified prefix.  If the
/// file does not exist yet, return it, otherwise add a suffix to make it
/// unique.
///
std::string llvm::getUniqueFilename(const std::string &FilenameBase) {
  if (!std::ifstream(FilenameBase.c_str()))
    return FilenameBase;    // Couldn't open the file? Use it!

  // Create a pattern for mkstemp...
  char *FNBuffer = new char[FilenameBase.size()+8];
  strcpy(FNBuffer, FilenameBase.c_str());
  strcpy(FNBuffer+FilenameBase.size(), "-XXXXXX");

  // Agree on a temporary file name to use....
#if defined(HAVE_MKSTEMP) && !defined(_MSC_VER)
  int TempFD;
  if ((TempFD = mkstemp(FNBuffer)) == -1) {
    // FIXME: this should return an emtpy string or something and allow the
    // caller to deal with the error!
    std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current "
	      << " directory!\n";
    exit(1);
  }

  // We don't need to hold the temp file descriptor... we will trust that no one
  // will overwrite/delete the file while we are working on it...
  close(TempFD);
#else
  // If we don't have mkstemp, use the old and obsolete mktemp function.
  if (mktemp(FNBuffer) == 0) {
    // FIXME: this should return an emtpy string or something and allow the
    // caller to deal with the error!
    std::cerr << "bugpoint: ERROR: Cannot create temporary file in the current "
              << " directory!\n";
    exit(1);
  }
#endif

  std::string Result(FNBuffer);
  delete[] FNBuffer;
  return Result;
}

static bool AddPermissionsBits (const std::string &Filename, int bits) {
  // Get the umask value from the operating system.  We want to use it
  // when changing the file's permissions. Since calling umask() sets
  // the umask and returns its old value, we must call it a second
  // time to reset it to the user's preference.
  int mask = umask(0777); // The arg. to umask is arbitrary.
  umask(mask);            // Restore the umask.

  // Get the file's current mode.
  struct stat st;
  if ((stat(Filename.c_str(), &st)) == -1)
    return false;

  // Change the file to have whichever permissions bits from 'bits'
  // that the umask would not disable.
  if ((chmod(Filename.c_str(), (st.st_mode | (bits & ~mask)))) == -1)
    return false;

  return true;
}

/// MakeFileExecutable - Make the file named Filename executable by
/// setting whichever execute permissions bits the process's current
/// umask would allow. Filename must name an existing file or
/// directory.  Returns true on success, false on error.
///
bool llvm::MakeFileExecutable(const std::string &Filename) {
  return AddPermissionsBits(Filename, 0111);
}

/// MakeFileReadable - Make the file named Filename readable by
/// setting whichever read permissions bits the process's current
/// umask would allow. Filename must name an existing file or
/// directory.  Returns true on success, false on error.
///
bool llvm::MakeFileReadable(const std::string &Filename) {
  return AddPermissionsBits(Filename, 0444);
}

/// getFileSize - Return the size of the specified file in bytes, or -1 if the
/// file cannot be read or does not exist.
long long llvm::getFileSize(const std::string &Filename) {
  struct stat StatBuf;
  if (stat(Filename.c_str(), &StatBuf) == -1)
    return -1;
  return StatBuf.st_size;
}

/// getFileTimestamp - Get the last modified time for the specified file in an
/// unspecified format.  This is useful to allow checking to see if a file was
/// updated since that last time the timestampt was aquired.  If the file does
/// not exist or there is an error getting the time-stamp, zero is returned.
unsigned long long llvm::getFileTimestamp(const std::string &Filename) {
  struct stat StatBuf;
  if (stat(Filename.c_str(), &StatBuf) == -1)
    return 0;
  return StatBuf.st_mtime;
}

/// ReadFileIntoAddressSpace - Attempt to map the specific file into the
/// address space of the current process for reading.  If this succeeds,
/// return the address of the buffer and the length of the file mapped.  On
/// failure, return null.
void *llvm::ReadFileIntoAddressSpace(const std::string &Filename,
                                     unsigned &Length) {
#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER)
  Length = (unsigned)getFileSize(Filename);
  if ((int)Length == -1) return 0;

  FDHandle FD(open(Filename.c_str(), O_RDONLY));
  if (FD == -1) return 0;

  // If the file has a length of zero, mmap might return a null pointer.  In
  // this case, allocate a single byte of memory and return it instead.
  if (Length == 0)
    return malloc(1);

  // mmap in the file all at once...
  void *Buffer = (void*)mmap(0, Length, PROT_READ, MAP_PRIVATE, FD, 0);

  if (Buffer == (void*)MAP_FAILED)
    return 0;

  return Buffer;
#else
  // FIXME: implement with read/write
#error Unimplemented ReadFileIntoAddressSpace - need to use read/write.
  return 0;
#endif
}

/// UnmapFileFromAddressSpace - Remove the specified file from the current
/// address space.
void llvm::UnmapFileFromAddressSpace(void *Buffer, unsigned Length) {
#if defined(HAVE_MMAP_FILE) && !defined(_MSC_VER)
  if (Length)
    munmap((char*)Buffer, Length);
  else
    free(Buffer);  // Zero byte files are malloc(1)'s.
#else
  free(Buffer);
#endif
}

//===----------------------------------------------------------------------===//
// FDHandle class implementation
//

FDHandle::~FDHandle() throw() {
  if (FD != -1) close(FD);
}

FDHandle &FDHandle::operator=(int fd) throw() {
  if (FD != -1) close(FD);
  FD = fd;
  return *this;
}

<|endoftext|>


<commit_before>#include "ExpertSystem/CLIPSFunctionBuilder.h"

CLIPSFunctionBuilder::CLIPSFunctionBuilder(std::string nm,
      FunctionNamer& namer) : CLIPSGlobalValueBuilder(nm, "Function",  namer) {
}

void CLIPSFunctionBuilder::build(Function* fn, KnowledgeConstructor* kc, bool traverseFields) {
   open();
   addFields(fn, kc, traverseFields);
   close();
   std::string str = getCompletedString();
   kc->addToKnowledgeBase((PointerAddress)arg, str);
}

void CLIPSFunctionBuilder::setCallingConvention(CallingConv::ID id) {
   const char* selection;
   switch(id) {
      case CallingConv::C:
         selection = "C";
         break;
      case CallingConv::Fast:
         selection = "Fast";
         break;
      case CallingConv::Cold:
         selection = "Cold";
         break;
      case CallingConv::GHC:
         selection = "GHC";
         break;
      case CallingConv::HiPE:
         selection = "HiPE";
         break;
      case CallingConv::FirstTargetCC:
         selection = "FirstTargetCC";
         break;
      case CallingConv::X86_StdCall:
         selection = "x86-stdcall";
         break;
      case CallingConv::X86_FastCall:
         selection = "x86-fastcall";
         break;
      case CallingConv::ARM_APCS:
         selection = "arm-apcs";
         break;
      case CallingConv::ARM_AAPCS:
         selection = "arm-aapcs";
         break;
      case CallingConv::ARM_AAPCS_VFB:
         selection = "arm-aapcs-vfb";
         break;
      case CallingConv::MSP430_INTR:
         selection = "msp430-intr";
         break;
      case CallingConv::X86_ThisCall:
         selection = "x86-thiscall";
         break;
      case CallingConv::PTX_Kernel:
         selection = "ptx-kernel";
         break;
      case CallingConv::PTX_Device:
         selection = "ptx-device";
         break;
      case CallingConv::MBLAZE_INTR:
         selection = "mblaze-intr";
            break;
      case CallingConv::MBLAZE_SVOL:
            selection = "mblaze-svol";
            break;
      case CallingConv::SPIR_FUNC:
            selection = "spir-func";
            break;
      case CallingConv::SPIR_KERNEL:
            selection = "spir-kernel";
            break;
      case CallingConv::Intel_OCL_BI:
            selection = "intel-ocl-bi";
            break;
      default:
            selection = "Unknown";
            break;
   }
   addField("CallingConvention", selection);
}

void CLIPSFunctionBuilder::addFields(Function* func, KnowledgeConstructor* kc, bool traverseFields) {
   CLIPSGlobalValueBuilder::addFields(func, kc);
   //this part contains the code for building the function itself
   FunctionNamer& namer = getNamer();
   addField("ReturnType", kc->route(fn->getReturnType(), namer));
   addField("FunctionType", kc->route(fn->getFunctionType(), namer));
   if(fn.isVarArg()) {
      addTrueField("IsVarArg");
   }
   addField("IntrinsicID", fn->getIntrinsicID());
   if(fn.isIntrinsic()) {
      addTrueField("IsIntrinsic");
   }
   setCallingConvention(func->getCallingConv(), kc);

   if(traverseFields) {

   }
}

<commit_msg>Continuing to implement CLIPSFunctionBuilder<commit_after>#include "ExpertSystem/CLIPSFunctionBuilder.h"

CLIPSFunctionBuilder::CLIPSFunctionBuilder(std::string nm,
      FunctionNamer& namer) : CLIPSGlobalValueBuilder(nm, "Function",  namer) {
}

void CLIPSFunctionBuilder::build(Function* fn, KnowledgeConstructor* kc) {
   open();
   addFields(fn, kc);
   close();
   std::string str = getCompletedString();
   kc->addToKnowledgeBase((PointerAddress)arg, str);
}

void CLIPSFunctionBuilder::setCallingConvention(CallingConv::ID id) {
   const char* selection;
   switch(id) {
      case CallingConv::C:
         selection = "C";
         break;
      case CallingConv::Fast:
         selection = "Fast";
         break;
      case CallingConv::Cold:
         selection = "Cold";
         break;
      case CallingConv::GHC:
         selection = "GHC";
         break;
      case CallingConv::HiPE:
         selection = "HiPE";
         break;
      case CallingConv::FirstTargetCC:
         selection = "FirstTargetCC";
         break;
      case CallingConv::X86_StdCall:
         selection = "x86-stdcall";
         break;
      case CallingConv::X86_FastCall:
         selection = "x86-fastcall";
         break;
      case CallingConv::ARM_APCS:
         selection = "arm-apcs";
         break;
      case CallingConv::ARM_AAPCS:
         selection = "arm-aapcs";
         break;
      case CallingConv::ARM_AAPCS_VFB:
         selection = "arm-aapcs-vfb";
         break;
      case CallingConv::MSP430_INTR:
         selection = "msp430-intr";
         break;
      case CallingConv::X86_ThisCall:
         selection = "x86-thiscall";
         break;
      case CallingConv::PTX_Kernel:
         selection = "ptx-kernel";
         break;
      case CallingConv::PTX_Device:
         selection = "ptx-device";
         break;
      case CallingConv::MBLAZE_INTR:
         selection = "mblaze-intr";
            break;
      case CallingConv::MBLAZE_SVOL:
            selection = "mblaze-svol";
            break;
      case CallingConv::SPIR_FUNC:
            selection = "spir-func";
            break;
      case CallingConv::SPIR_KERNEL:
            selection = "spir-kernel";
            break;
      case CallingConv::Intel_OCL_BI:
            selection = "intel-ocl-bi";
            break;
      default:
            selection = "Unknown";
            break;
   }
   addField("CallingConvention", selection);
}
void CLIPSFunctionBuilder::setAttributes(const AttributeSet& attr) {

}
void CLIPSFunctionBuilder::addFields(Function* func,
      KnowledgeConstructor* kc) {

   CLIPSGlobalValueBuilder::addFields(func, kc);
   //this part contains the code for building the function itself
   FunctionNamer& namer = getNamer();
   addField("ReturnType", kc->route(fn->getReturnType(), namer));
   addField("FunctionType", kc->route(fn->getFunctionType(), namer));
   if(fn.isVarArg()) {
      addTrueField("IsVarArg");
   }
   addField("IntrinsicID", fn->getIntrinsicID());
   if(fn.isIntrinsic()) {
      addTrueField("IsIntrinsic");
   }
   setCallingConvention(func->getCallingConv());
   setAttributes(func->getAttributes());
   if(fn.hasGC()) {
      addTrueField("HasGC");
   }
   if(fn.doesNotAccessMemory()) {
      addTrueField("DoesNotAccessMemory");
   }
   if(fn.onlyReadsMemory()) {
      addTrueField("OnlyReadsMemory");
   }
   if(fn.doesNotReturn()) {
      addTrueField("DoesNotReturn");
   }
   if(fn.cannotDuplicate()) {
      addTrueField("CannotDuplicate");
   }
   if(fn.hasUWTable()) {
      addTrueField("HasUWTable");
   }
   if(fn.needsUnwindTableEntry()) {
      addTrueField("NeedsUnwindTableEntry");
   }
   if(fn.hasStructRetAttr()) {
      addTrueField("HasStructRetAttr");
   }
   //TODO: Expose doesNotAlias, doesNotCapture, and getParamAttributes to
   //CLIPS as functions
   char* fnName = (char*)fn.getName().data();
   FunctionNamer& namer = getNamer();
   addField("EntryBlock", kc->route(fn.getEntryBlock(), fnName, namer));

   if(traverseFields) {

   }
}

<|endoftext|>