<commit_before>//------------------------------------------------------------------------------
//  DrawCallPerf.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Render/RenderFacade.h"
#include "Render/Util/RawMeshLoader.h"
#include "Render/Util/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/random.hpp"
#include <chrono>
#include "shaders.h"

using namespace Oryol;
using namespace Oryol::Core;
using namespace Oryol::Render;
using namespace Oryol::Resource;

// derived application class
class DrawCallPerfApp : public App {
public:
    virtual AppState::Code OnInit();
    virtual AppState::Code OnRunning();
    virtual AppState::Code OnCleanup();

private:
    void updateCamera();
    void emitParticles();
    void updateParticles();

    RenderFacade* render = nullptr;
    Resource::Id meshId;
    Resource::Id progId;
    Resource::Id stateId;
    glm::mat4 view;
    glm::mat4 proj;
    glm::mat4 model;
    glm::mat4 modelViewProj;
    int32 frameCount = 0;
    int32 curNumParticles = 0;
    std::chrono::time_point<std::chrono::high_resolution_clock> lastFrameTimePoint;
    static const int32 MaxNumParticles = 1<<16;
    struct {
        glm::vec4 pos;
        glm::vec4 vec;
    } particles[MaxNumParticles];
};
OryolMain(DrawCallPerfApp);

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnInit() {
    // setup rendering system
    this->render = RenderFacade::CreateSingle(RenderSetup::Windowed(800, 500, "Oryol DrawCallPerf Sample"));
    this->render->AttachLoader(RawMeshLoader::Create());

    // create a small cube shape
    ShapeBuilder shapeBuilder;
    shapeBuilder.SetRandomColorsFlag(true);
    shapeBuilder.AddComponent(VertexAttr::Position, VertexFormat::Float3);
    shapeBuilder.AddComponent(VertexAttr::Color0, VertexFormat::Float4);
    shapeBuilder.AddBox(0.05f, 0.05f, 0.05f, 1);
    shapeBuilder.Build();
    this->meshId = this->render->CreateResource(MeshSetup::FromData("box"), shapeBuilder.GetStream());

    // build a shader program from vs/fs sources
    this->progId = this->render->CreateResource(Shaders::Main::CreateSetup());

    // setup state block object
    StateBlockSetup stateSetup("state");
    stateSetup.AddState(Render::State::DepthMask, true);
    stateSetup.AddState(Render::State::DepthTestEnabled, true);
    stateSetup.AddState(Render::State::DepthFunc, Render::State::LessEqual);
    stateSetup.AddState(Render::State::ClearDepth, 1.0f);
    stateSetup.AddState(Render::State::ClearColor, 0.0f, 0.0f, 0.0f, 0.0f);
    this->stateId = this->render->CreateResource(stateSetup);

    // setup projection and view matrices
    const float32 fbWidth = this->render->GetDisplayAttrs().GetFramebufferWidth();
    const float32 fbHeight = this->render->GetDisplayAttrs().GetFramebufferHeight();
    this->proj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::lookAt(glm::vec3(0.0f, 2.5f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->model = glm::mat4();
    this->modelViewProj = this->proj * this->view * this->model;

    return App::OnInit();
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::updateCamera() {
    float32 angle = this->frameCount * 0.01f;
    glm::vec3 pos(glm::sin(angle) * 10.0f, 2.5f, glm::cos(angle) * 10.0f);
    this->view = glm::lookAt(pos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->modelViewProj = this->proj * this->view * this->model;
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::emitParticles() {
    if (this->curNumParticles < MaxNumParticles) {
        this->particles[this->curNumParticles].pos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
        glm::vec3 rnd = glm::ballRand(0.5f);
        rnd.y += 2.0f;
        this->particles[this->curNumParticles].vec = glm::vec4(rnd, 0.0f);
        this->curNumParticles++;
    }
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::updateParticles() {
    const float32 frameTime = 1.0f / 60.0f;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        auto& curParticle = this->particles[i];
        curParticle.vec.y -= 1.0f * frameTime;
        curParticle.pos += curParticle.vec * frameTime;
        if (curParticle.pos.y < -2.0f) {
            curParticle.pos.y = -1.8f;
            curParticle.vec.y = -curParticle.vec.y;
            curParticle.vec *= 0.8f;
        }
    }
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnRunning() {

    // FIXME: that chrono code is ugly, create our own wrapper Time module?

    using namespace std;

    chrono::microseconds updTime;
    chrono::microseconds drawTime;
    this->frameCount++;
    if (this->render->BeginFrame()) {

        // update block
        auto updStart = chrono::high_resolution_clock::now();
        this->updateCamera();
        this->emitParticles();
        this->updateParticles();
        updTime = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - updStart);

        // render block
        this->render->ApplyStateBlock(this->stateId);
        this->render->Clear(true, true, true);
        this->render->ApplyMesh(this->meshId);
        this->render->ApplyProgram(this->progId, 0);
        this->render->ApplyVariable(Shaders::Main::ModelViewProjection, this->modelViewProj);

        auto drawStart = chrono::high_resolution_clock::now();
        for (int32 i = 0; i < this->curNumParticles; i++) {
            this->render->ApplyVariable(Shaders::Main::ParticleTranslate, this->particles[i].pos);
            this->render->Draw(0);
        }
        drawTime = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - drawStart);
        this->render->EndFrame();
    }

    auto curTime = chrono::high_resolution_clock::now();
    auto frameTime = chrono::duration_cast<chrono::microseconds>(curTime - this->lastFrameTimePoint);
    this->lastFrameTimePoint = curTime;

    if (0 == (this->curNumParticles % 200)) {
        Log::Info("%d draws: upd=%lld draw=%lld, frame=%lld microseconds\n",
                  this->curNumParticles,
                  updTime.count(),
                  drawTime.count(),
                  frameTime.count());
    }

    return render->QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnCleanup() {
    // cleanup everything
    this->render->DiscardResource(this->stateId);
    this->render->DiscardResource(this->progId);
    this->render->DiscardResource(this->meshId);
    this->render = nullptr;
    RenderFacade::DestroySingle();
    return App::OnCleanup();
}
<commit_msg>Fixed printf formatting warning on Linux<commit_after>//------------------------------------------------------------------------------
//  DrawCallPerf.cc
//------------------------------------------------------------------------------
#include "Pre.h"
#include "Core/App.h"
#include "Render/RenderFacade.h"
#include "Render/Util/RawMeshLoader.h"
#include "Render/Util/ShapeBuilder.h"
#include "glm/mat4x4.hpp"
#include "glm/gtc/matrix_transform.hpp"
#include "glm/gtc/random.hpp"
#include <chrono>
#include "shaders.h"

using namespace Oryol;
using namespace Oryol::Core;
using namespace Oryol::Render;
using namespace Oryol::Resource;

// derived application class
class DrawCallPerfApp : public App {
public:
    virtual AppState::Code OnInit();
    virtual AppState::Code OnRunning();
    virtual AppState::Code OnCleanup();

private:
    void updateCamera();
    void emitParticles();
    void updateParticles();

    RenderFacade* render = nullptr;
    Resource::Id meshId;
    Resource::Id progId;
    Resource::Id stateId;
    glm::mat4 view;
    glm::mat4 proj;
    glm::mat4 model;
    glm::mat4 modelViewProj;
    int32 frameCount = 0;
    int32 curNumParticles = 0;
    std::chrono::time_point<std::chrono::high_resolution_clock> lastFrameTimePoint;
    static const int32 MaxNumParticles = 1<<16;
    struct {
        glm::vec4 pos;
        glm::vec4 vec;
    } particles[MaxNumParticles];
};
OryolMain(DrawCallPerfApp);

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnInit() {
    // setup rendering system
    this->render = RenderFacade::CreateSingle(RenderSetup::Windowed(800, 500, "Oryol DrawCallPerf Sample"));
    this->render->AttachLoader(RawMeshLoader::Create());

    // create a small cube shape
    ShapeBuilder shapeBuilder;
    shapeBuilder.SetRandomColorsFlag(true);
    shapeBuilder.AddComponent(VertexAttr::Position, VertexFormat::Float3);
    shapeBuilder.AddComponent(VertexAttr::Color0, VertexFormat::Float4);
    shapeBuilder.AddBox(0.05f, 0.05f, 0.05f, 1);
    shapeBuilder.Build();
    this->meshId = this->render->CreateResource(MeshSetup::FromData("box"), shapeBuilder.GetStream());

    // build a shader program from vs/fs sources
    this->progId = this->render->CreateResource(Shaders::Main::CreateSetup());

    // setup state block object
    StateBlockSetup stateSetup("state");
    stateSetup.AddState(Render::State::DepthMask, true);
    stateSetup.AddState(Render::State::DepthTestEnabled, true);
    stateSetup.AddState(Render::State::DepthFunc, Render::State::LessEqual);
    stateSetup.AddState(Render::State::ClearDepth, 1.0f);
    stateSetup.AddState(Render::State::ClearColor, 0.0f, 0.0f, 0.0f, 0.0f);
    this->stateId = this->render->CreateResource(stateSetup);

    // setup projection and view matrices
    const float32 fbWidth = this->render->GetDisplayAttrs().GetFramebufferWidth();
    const float32 fbHeight = this->render->GetDisplayAttrs().GetFramebufferHeight();
    this->proj = glm::perspectiveFov(glm::radians(45.0f), fbWidth, fbHeight, 0.01f, 100.0f);
    this->view = glm::lookAt(glm::vec3(0.0f, 2.5f, 0.0f), glm::vec3(0.0f, 0.0f, -10.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->model = glm::mat4();
    this->modelViewProj = this->proj * this->view * this->model;

    return App::OnInit();
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::updateCamera() {
    float32 angle = this->frameCount * 0.01f;
    glm::vec3 pos(glm::sin(angle) * 10.0f, 2.5f, glm::cos(angle) * 10.0f);
    this->view = glm::lookAt(pos, glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
    this->modelViewProj = this->proj * this->view * this->model;
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::emitParticles() {
    if (this->curNumParticles < MaxNumParticles) {
        this->particles[this->curNumParticles].pos = glm::vec4(0.0f, 0.0f, 0.0f, 0.0f);
        glm::vec3 rnd = glm::ballRand(0.5f);
        rnd.y += 2.0f;
        this->particles[this->curNumParticles].vec = glm::vec4(rnd, 0.0f);
        this->curNumParticles++;
    }
}

//------------------------------------------------------------------------------
void
DrawCallPerfApp::updateParticles() {
    const float32 frameTime = 1.0f / 60.0f;
    for (int32 i = 0; i < this->curNumParticles; i++) {
        auto& curParticle = this->particles[i];
        curParticle.vec.y -= 1.0f * frameTime;
        curParticle.pos += curParticle.vec * frameTime;
        if (curParticle.pos.y < -2.0f) {
            curParticle.pos.y = -1.8f;
            curParticle.vec.y = -curParticle.vec.y;
            curParticle.vec *= 0.8f;
        }
    }
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnRunning() {

    // FIXME: that chrono code is ugly, create our own wrapper Time module?

    using namespace std;

    chrono::microseconds updTime;
    chrono::microseconds drawTime;
    this->frameCount++;
    if (this->render->BeginFrame()) {

        // update block
        auto updStart = chrono::high_resolution_clock::now();
        this->updateCamera();
        this->emitParticles();
        this->updateParticles();
        updTime = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - updStart);

        // render block
        this->render->ApplyStateBlock(this->stateId);
        this->render->Clear(true, true, true);
        this->render->ApplyMesh(this->meshId);
        this->render->ApplyProgram(this->progId, 0);
        this->render->ApplyVariable(Shaders::Main::ModelViewProjection, this->modelViewProj);

        auto drawStart = chrono::high_resolution_clock::now();
        for (int32 i = 0; i < this->curNumParticles; i++) {
            this->render->ApplyVariable(Shaders::Main::ParticleTranslate, this->particles[i].pos);
            this->render->Draw(0);
        }
        drawTime = chrono::duration_cast<chrono::microseconds>(chrono::high_resolution_clock::now() - drawStart);
        this->render->EndFrame();
    }

    auto curTime = chrono::high_resolution_clock::now();
    auto frameTime = chrono::duration_cast<chrono::microseconds>(curTime - this->lastFrameTimePoint);
    this->lastFrameTimePoint = curTime;

    if (0 == (this->curNumParticles % 200)) {
        Log::Info("%d draws: upd=%lld draw=%lld, frame=%lld microseconds\n",
                  this->curNumParticles,
                  (long long int)updTime.count(),
                  (long long int)drawTime.count(),
                  (long long int)frameTime.count());
    }

    return render->QuitRequested() ? AppState::Cleanup : AppState::Running;
}

//------------------------------------------------------------------------------
AppState::Code
DrawCallPerfApp::OnCleanup() {
    // cleanup everything
    this->render->DiscardResource(this->stateId);
    this->render->DiscardResource(this->progId);
    this->render->DiscardResource(this->meshId);
    this->render = nullptr;
    RenderFacade::DestroySingle();
    return App::OnCleanup();
}
<|endoftext|>


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

#include "QUECTEL_EC2X.h"

#include "PinNames.h"
#include "AT_CellularNetwork.h"
#include "rtos/ThisThread.h"

using namespace mbed;
using namespace rtos;
using namespace events;

static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
    AT_CellularNetwork::RegistrationModeLAC,    // C_EREG
    AT_CellularNetwork::RegistrationModeLAC,    // C_GREG
    AT_CellularNetwork::RegistrationModeEnable,    // C_REG
    1,  // AT_CGSN_WITH_TYPE
    1,  // AT_CGDATA
    0,  // AT_CGAUTH
    1,  // AT_CNMI
    1,  // AT_CSMP
    1,  // AT_CMGF
    1,  // AT_CSDH
    1,  // PROPERTY_IPV4_STACK
    1,  // PROPERTY_IPV6_STACK
    1,  // PROPERTY_IPV4V6_STACK
    0,  // PROPERTY_NON_IP_PDP_TYPE
    1,  // PROPERTY_AT_CGEREP
};

QUECTEL_EC2X::QUECTEL_EC2X(FileHandle *fh, PinName pwr, PinName rst)
    : AT_CellularDevice(fh),
      _pwr_key(pwr, 0),
      _rst(rst, 0)

{
    AT_CellularBase::set_cellular_properties(cellular_properties);
}

#if MBED_CONF_QUECTEL_EC2X_PROVIDE_DEFAULT
#include "UARTSerial.h"
CellularDevice *CellularDevice::get_default_instance()
{
    static UARTSerial serial(MBED_CONF_QUECTEL_EC2X_TX,
                             MBED_CONF_QUECTEL_EC2X_RX,
                             MBED_CONF_QUECTEL_EC2X_BAUDRATE);
#if defined(MBED_CONF_QUECTEL_EC2X_RTS) && defined(MBED_CONF_QUECTEL_EC2X_CTS)
    serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_QUECTEL_EC2X_RTS, MBED_CONF_QUECTEL_EC2X_CTS);
#endif
    static QUECTEL_EC2X device(&serial, MBED_CONF_QUECTEL_EC2X_PWR, MBED_CONF_QUECTEL_EC2X_RST);
    return &device;
}

nsapi_error_t QUECTEL_EC2X::hard_power_on()
{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(600);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::hard_power_off()

{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(750);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::soft_power_on()
{
    if (_rst.is_connected()) {
        _rst = 1;
        ThisThread::sleep_for(460);
        _rst = 0;
        ThisThread::sleep_for(100);
    }

    _at->lock();

    _at->set_at_timeout(5000);
    _at->resp_start();
    _at->set_stop_tag("RDY");
    bool rdy = _at->consume_to_stop_tag();
    _at->set_stop_tag(OK);

    _at->unlock();

    if (!rdy) {
        return NSAPI_ERROR_DEVICE_ERROR;
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::soft_power_off()
{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(750);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

#endif
<commit_msg>CREG can handle lac/ci/lat<commit_after>/*
 * Copyright (c) 2019, Arm Limited and affiliates.
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "QUECTEL_EC2X.h"

#include "PinNames.h"
#include "AT_CellularNetwork.h"
#include "rtos/ThisThread.h"

using namespace mbed;
using namespace rtos;
using namespace events;

static const intptr_t cellular_properties[AT_CellularBase::PROPERTY_MAX] = {
    AT_CellularNetwork::RegistrationModeLAC,    // C_EREG
    AT_CellularNetwork::RegistrationModeLAC,    // C_GREG
    AT_CellularNetwork::RegistrationModeLAC,    // C_REG
    1,  // AT_CGSN_WITH_TYPE
    1,  // AT_CGDATA
    0,  // AT_CGAUTH
    1,  // AT_CNMI
    1,  // AT_CSMP
    1,  // AT_CMGF
    1,  // AT_CSDH
    1,  // PROPERTY_IPV4_STACK
    1,  // PROPERTY_IPV6_STACK
    1,  // PROPERTY_IPV4V6_STACK
    0,  // PROPERTY_NON_IP_PDP_TYPE
    1,  // PROPERTY_AT_CGEREP
};

QUECTEL_EC2X::QUECTEL_EC2X(FileHandle *fh, PinName pwr, PinName rst)
    : AT_CellularDevice(fh),
      _pwr_key(pwr, 0),
      _rst(rst, 0)

{
    AT_CellularBase::set_cellular_properties(cellular_properties);
}

#if MBED_CONF_QUECTEL_EC2X_PROVIDE_DEFAULT
#include "UARTSerial.h"
CellularDevice *CellularDevice::get_default_instance()
{
    static UARTSerial serial(MBED_CONF_QUECTEL_EC2X_TX,
                             MBED_CONF_QUECTEL_EC2X_RX,
                             MBED_CONF_QUECTEL_EC2X_BAUDRATE);
#if defined(MBED_CONF_QUECTEL_EC2X_RTS) && defined(MBED_CONF_QUECTEL_EC2X_CTS)
    serial.set_flow_control(SerialBase::RTSCTS, MBED_CONF_QUECTEL_EC2X_RTS, MBED_CONF_QUECTEL_EC2X_CTS);
#endif
    static QUECTEL_EC2X device(&serial, MBED_CONF_QUECTEL_EC2X_PWR, MBED_CONF_QUECTEL_EC2X_RST);
    return &device;
}

nsapi_error_t QUECTEL_EC2X::hard_power_on()
{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(600);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::hard_power_off()

{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(750);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::soft_power_on()
{
    if (_rst.is_connected()) {
        _rst = 1;
        ThisThread::sleep_for(460);
        _rst = 0;
        ThisThread::sleep_for(100);
    }

    _at->lock();

    _at->set_at_timeout(5000);
    _at->resp_start();
    _at->set_stop_tag("RDY");
    bool rdy = _at->consume_to_stop_tag();
    _at->set_stop_tag(OK);

    _at->unlock();

    if (!rdy) {
        return NSAPI_ERROR_DEVICE_ERROR;
    }

    return NSAPI_ERROR_OK;
}

nsapi_error_t QUECTEL_EC2X::soft_power_off()
{
    if (_pwr_key.is_connected()) {
        _pwr_key = 1;
        ThisThread::sleep_for(750);
        _pwr_key = 0;
        ThisThread::sleep_for(100);
    }

    return NSAPI_ERROR_OK;
}

#endif
<|endoftext|>


<commit_before>#include <atomic>

extern "C" {
#if 0
}
#endif

int load_acquire(std::atomic<int> *x) {
	return x->load(std::memory_order_acquire);
}

void load_acquire_loop(std::atomic<int> *x) {
	while (x->load(std::memory_order_acquire) == 0);
}

int load_consume(std::atomic<int> *x) {
	return x->load(std::memory_order_consume);
}

void store_release(std::atomic<int> *x) {
	x->store(1, std::memory_order_release);
}

int load_sc(std::atomic<int> *x) {
	return x->load(std::memory_order_seq_cst);
}
void store_sc(std::atomic<int> *x) {
	x->store(1, std::memory_order_seq_cst);
}

int double_sc(std::atomic<int> *x, std::atomic<int> *y) {
	int z = x->load(std::memory_order_seq_cst);
	y->store(1, std::memory_order_seq_cst);
	return z;
}

int load_relaxed(std::atomic<int> *x) {
	return x->load(std::memory_order_relaxed);
}
void store_relaxed(std::atomic<int> *x) {
	x->store(1, std::memory_order_relaxed);
}

int rmw_acquire(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_acquire);
}
int rmw_acq_rel(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_acq_rel);
}
int rmw_seq_cst(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_seq_cst);
}

int cas_rel__acq(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_release, std::memory_order_acquire);
    return exp;
}
int cas_acq_rel__acq(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_acq_rel, std::memory_order_acquire);
    return exp;
}
int cas_acq_rel__rlx(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_acq_rel, std::memory_order_relaxed);
    return exp;
}

int main() { return 0; }
}
<commit_msg>Add some more things to fragments.cpp<commit_after>#include <atomic>

extern "C" {
#if 0
}
#endif

int load_acquire(std::atomic<int> *x) {
	return x->load(std::memory_order_acquire);
}

void load_acquire_loop(std::atomic<int> *x) {
	while (x->load(std::memory_order_acquire) == 0);
}

int load_consume(std::atomic<int> *x) {
	return x->load(std::memory_order_consume);
}

void store_release(std::atomic<int> *x) {
	x->store(1, std::memory_order_release);
}

int load_sc(std::atomic<int> *x) {
	return x->load(std::memory_order_seq_cst);
}
void store_sc(std::atomic<int> *x) {
	x->store(1, std::memory_order_seq_cst);
}

int double_sc(std::atomic<int> *x, std::atomic<int> *y) {
	int z = x->load(std::memory_order_seq_cst);
	y->store(1, std::memory_order_seq_cst);
	return z;
}

int load_relaxed(std::atomic<int> *x) {
	return x->load(std::memory_order_relaxed);
}
void store_relaxed(std::atomic<int> *x) {
	x->store(1, std::memory_order_relaxed);
}

int rmw_and_acquire(std::atomic<int> *x) {
    return std::atomic_fetch_and_explicit(x, 1, std::memory_order_acquire);
}
void rmw_and_ignore_res(std::atomic<int> *x) {
    std::atomic_fetch_and_explicit(x, 1, std::memory_order_relaxed);
}

int rmw_acquire(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_acquire);
}
int rmw_acq_rel(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_acq_rel);
}
int rmw_seq_cst(std::atomic<int> *x) {
    return std::atomic_fetch_add_explicit(x, 1, std::memory_order_seq_cst);
}

int cas_rel__acq(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_release, std::memory_order_acquire);
    return exp;
}
int cas_acq_rel__acq(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_acq_rel, std::memory_order_acquire);
    return exp;
}
int cas_acq_rel__rlx(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_strong_explicit(
        x, &exp, 1, std::memory_order_acq_rel, std::memory_order_relaxed);
    return exp;
}

int cas_weak(std::atomic<int> *x) {
    int exp = 0;
    std::atomic_compare_exchange_weak_explicit(
        x, &exp, 1, std::memory_order_acq_rel, std::memory_order_acquire);
    return exp;
}

int main() { return 0; }
}
<|endoftext|>


<commit_before>/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015-2016 Pivotal Software, Inc.
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#include "catalog/CatalogRelation.hpp"

#include <memory>
#include <string>
#include <vector>

#include "catalog/Catalog.pb.h"
#include "catalog/CatalogAttribute.hpp"
#include "catalog/CatalogConfig.h"
#include "catalog/CatalogRelationSchema.hpp"

#ifdef QUICKSTEP_HAVE_LIBNUMA
#include "catalog/NUMAPlacementScheme.hpp"
#endif

#include "catalog/PartitionScheme.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "threading/SpinSharedMutex.hpp"
#include "utility/PtrVector.hpp"

#include "glog/logging.h"

namespace quickstep {

class Type;

bool CatalogRelation::ProtoIsValid(const serialization::CatalogRelationSchema &proto) {
  // Check that proto is fully initialized.
  if (!CatalogRelationSchema::ProtoIsValid(proto) ||
      !proto.HasExtension(serialization::CatalogRelation::default_layout)) {
    return false;
  }

  // Check if the proto of the relation has a partition scheme.
  if (proto.HasExtension(serialization::CatalogRelation::partition_scheme)) {
    // Check if the partition scheme protobuf is valid.
    if (!PartitionScheme::ProtoIsValid(
            proto.GetExtension(serialization::CatalogRelation::partition_scheme))) {
      return false;
    }

#ifdef QUICKSTEP_HAVE_LIBNUMA
    // Check if the proto of the relation has a NUMA placement scheme.
    if (proto.HasExtension(serialization::CatalogRelation::placement_scheme)) {
      // Check if the NUMA placement scheme protobuf is valid.
      if (!NUMAPlacementScheme::ProtoIsValid(
              proto.GetExension(serialization::CatalogRelation::placement_scheme))) {
        return false;
      }
    }
#endif
  }

  // Catalog Relation's proto is valid.
  return true;
}

CatalogRelation::CatalogRelation(const serialization::CatalogRelationSchema &proto)
    : CatalogRelationSchema(proto),
      default_layout_(nullptr) {
  DCHECK(ProtoIsValid(proto))
      << "Attempted to create CatalogRelation from an invalid proto description:\n"
      << proto.DebugString();

  // Deserializing the partition scheme for the relation.
  // This should be done after the attributes are added and before the
  // blocks of the relation are added.
  if (proto.HasExtension(serialization::CatalogRelation::partition_scheme)) {
    const serialization::PartitionScheme &proto_partition_scheme =
        proto.GetExtension(serialization::CatalogRelation::partition_scheme);

    const attribute_id partition_attribute_id = proto_partition_scheme.header().partition_attribute_id();
    DCHECK(hasAttributeWithId(partition_attribute_id));
    const Type &attr_type = attr_vec_[partition_attribute_id].getType();

    setPartitionScheme(PartitionScheme::ReconstructFromProto(proto_partition_scheme, attr_type));

    // Deserializing the NUMA placement scheme for the relation.
#ifdef QUICKSTEP_HAVE_LIBNUMA
    if (proto.HasExtension(serialization::CatalogRelation::placement_scheme)) {
      setNUMAPlacementScheme(
          NUMAPlacementScheme::ReconstructFromProto(
              proto.GetExtension(serialization::CatalogRelation::placement_scheme),
              proto_partition_scheme.header().num_partitions()));
    }
#endif
  }

  const StorageBlockLayoutDescription &proto_default_layout =
      proto.GetExtension(serialization::CatalogRelation::default_layout);
  DCHECK(StorageBlockLayout::DescriptionIsValid(*this, proto_default_layout));

  // Deserializing the index scheme defined for the relation, if any.
  if (proto.HasExtension(serialization::CatalogRelation::index_scheme)) {
    index_scheme_.reset(
        IndexScheme::ReconstructFromProto(proto.GetExtension(serialization::CatalogRelation::index_scheme)));
    // Ensure that indices present in the block layout are the same as in the index scheme.
    const std::size_t num_indices_expected = index_scheme_->getNumIndices();
    const std::size_t num_indices_checked = proto_default_layout.index_description_size();
    DCHECK_EQ(num_indices_expected, num_indices_checked);
    for (std::size_t i = 0; i < num_indices_checked; ++i) {
      const IndexSubBlockDescription &description_checked = proto_default_layout.index_description(i);
      DCHECK(index_scheme_->hasIndexWithDescription(description_checked))
          << "Block layout defines some indices not present in the catalog";
    }
  }

  // Deserializing the blocks of the relation.
  for (int i = 0; i < proto.ExtensionSize(serialization::CatalogRelation::blocks); ++i) {
    blocks_.emplace_back(static_cast<block_id>(proto.GetExtension(serialization::CatalogRelation::blocks, i)));
  }

  default_layout_.reset(new StorageBlockLayout(*this, proto_default_layout));
}

serialization::CatalogRelationSchema CatalogRelation::getProto() const {
  serialization::CatalogRelationSchema proto;

  proto.set_relation_id(id_);
  proto.set_name(name_);
  proto.set_temporary(temporary_);

  for (PtrVector<CatalogAttribute, true>::const_iterator it = attr_vec_.begin();
       it != attr_vec_.end();
       ++it) {
    if (it.isNull()) {
      proto.add_attributes();
    } else {
      proto.add_attributes()->MergeFrom(it->getProto());
    }
  }

  proto.MutableExtension(serialization::CatalogRelation::default_layout)
      ->MergeFrom(getDefaultStorageBlockLayout().getDescription());

  {
    SpinSharedMutexSharedLock<false> lock(blocks_mutex_);
    for (const block_id block : blocks_) {
      proto.AddExtension(serialization::CatalogRelation::blocks, block);
    }
  }

  if (hasIndexScheme()) {
    proto.MutableExtension(serialization::CatalogRelation::index_scheme)->MergeFrom(index_scheme_->getProto());
  }

  // The partition scheme of the relation is stored in the protocol buffer format.
  if (hasPartitionScheme()) {
    proto.MutableExtension(serialization::CatalogRelation::partition_scheme)
        ->MergeFrom(partition_scheme_->getProto());
  }

  return proto;
}

void CatalogRelation::setPartitionScheme(PartitionScheme* partition_scheme) {
  DCHECK_EQ(0u, size_blocks());
  partition_scheme_.reset(partition_scheme);
}

void CatalogRelation::setDefaultStorageBlockLayout(StorageBlockLayout *default_layout) {
  DCHECK(&(default_layout->getRelation()) == this);
  default_layout_.reset(default_layout);
}

const StorageBlockLayout& CatalogRelation::getDefaultStorageBlockLayout() const {
  if (default_layout_ == nullptr) {
    default_layout_.reset(StorageBlockLayout::GenerateDefaultLayout(*this, isVariableLength()));
  }

  return *default_layout_;
}

}  // namespace quickstep
<commit_msg>Added the missing serialization for NUMA Placement scheme.<commit_after>/**
 *   Copyright 2011-2015 Quickstep Technologies LLC.
 *   Copyright 2015-2016 Pivotal Software, Inc.
 *   Copyright 2016, Quickstep Research Group, Computer Sciences Department,
 *     University of Wisconsin—Madison.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 **/

#include "catalog/CatalogRelation.hpp"

#include <memory>
#include <string>
#include <vector>

#include "catalog/Catalog.pb.h"
#include "catalog/CatalogAttribute.hpp"
#include "catalog/CatalogConfig.h"
#include "catalog/CatalogRelationSchema.hpp"

#ifdef QUICKSTEP_HAVE_LIBNUMA
#include "catalog/NUMAPlacementScheme.hpp"
#endif

#include "catalog/PartitionScheme.hpp"
#include "storage/StorageBlockInfo.hpp"
#include "storage/StorageBlockLayout.hpp"
#include "storage/StorageBlockLayout.pb.h"
#include "threading/SpinSharedMutex.hpp"
#include "utility/PtrVector.hpp"

#include "glog/logging.h"

namespace quickstep {

class Type;

bool CatalogRelation::ProtoIsValid(const serialization::CatalogRelationSchema &proto) {
  // Check that proto is fully initialized.
  if (!CatalogRelationSchema::ProtoIsValid(proto) ||
      !proto.HasExtension(serialization::CatalogRelation::default_layout)) {
    return false;
  }

  // Check if the proto of the relation has a partition scheme.
  if (proto.HasExtension(serialization::CatalogRelation::partition_scheme)) {
    // Check if the partition scheme protobuf is valid.
    if (!PartitionScheme::ProtoIsValid(
            proto.GetExtension(serialization::CatalogRelation::partition_scheme))) {
      return false;
    }

#ifdef QUICKSTEP_HAVE_LIBNUMA
    // Check if the proto of the relation has a NUMA placement scheme.
    if (proto.HasExtension(serialization::CatalogRelation::placement_scheme)) {
      // Check if the NUMA placement scheme protobuf is valid.
      if (!NUMAPlacementScheme::ProtoIsValid(
              proto.GetExtension(serialization::CatalogRelation::placement_scheme))) {
        return false;
      }
    }
#endif
  }

  // Catalog Relation's proto is valid.
  return true;
}

CatalogRelation::CatalogRelation(const serialization::CatalogRelationSchema &proto)
    : CatalogRelationSchema(proto),
      default_layout_(nullptr) {
  DCHECK(ProtoIsValid(proto))
      << "Attempted to create CatalogRelation from an invalid proto description:\n"
      << proto.DebugString();

  // Deserializing the partition scheme for the relation.
  // This should be done after the attributes are added and before the
  // blocks of the relation are added.
  if (proto.HasExtension(serialization::CatalogRelation::partition_scheme)) {
    const serialization::PartitionScheme &proto_partition_scheme =
        proto.GetExtension(serialization::CatalogRelation::partition_scheme);

    const attribute_id partition_attribute_id = proto_partition_scheme.header().partition_attribute_id();
    DCHECK(hasAttributeWithId(partition_attribute_id));
    const Type &attr_type = attr_vec_[partition_attribute_id].getType();

    setPartitionScheme(PartitionScheme::ReconstructFromProto(proto_partition_scheme, attr_type));

    // Deserializing the NUMA placement scheme for the relation.
#ifdef QUICKSTEP_HAVE_LIBNUMA
    if (proto.HasExtension(serialization::CatalogRelation::placement_scheme)) {
      setNUMAPlacementScheme(
          NUMAPlacementScheme::ReconstructFromProto(
              proto.GetExtension(serialization::CatalogRelation::placement_scheme),
              proto_partition_scheme.header().num_partitions()));
    }
#endif
  }

  const StorageBlockLayoutDescription &proto_default_layout =
      proto.GetExtension(serialization::CatalogRelation::default_layout);
  DCHECK(StorageBlockLayout::DescriptionIsValid(*this, proto_default_layout));

  // Deserializing the index scheme defined for the relation, if any.
  if (proto.HasExtension(serialization::CatalogRelation::index_scheme)) {
    index_scheme_.reset(
        IndexScheme::ReconstructFromProto(proto.GetExtension(serialization::CatalogRelation::index_scheme)));
    // Ensure that indices present in the block layout are the same as in the index scheme.
    const std::size_t num_indices_expected = index_scheme_->getNumIndices();
    const std::size_t num_indices_checked = proto_default_layout.index_description_size();
    DCHECK_EQ(num_indices_expected, num_indices_checked);
    for (std::size_t i = 0; i < num_indices_checked; ++i) {
      const IndexSubBlockDescription &description_checked = proto_default_layout.index_description(i);
      DCHECK(index_scheme_->hasIndexWithDescription(description_checked))
          << "Block layout defines some indices not present in the catalog";
    }
  }

  // Deserializing the blocks of the relation.
  for (int i = 0; i < proto.ExtensionSize(serialization::CatalogRelation::blocks); ++i) {
    blocks_.emplace_back(static_cast<block_id>(proto.GetExtension(serialization::CatalogRelation::blocks, i)));
  }

  default_layout_.reset(new StorageBlockLayout(*this, proto_default_layout));
}

serialization::CatalogRelationSchema CatalogRelation::getProto() const {
  serialization::CatalogRelationSchema proto;

  proto.set_relation_id(id_);
  proto.set_name(name_);
  proto.set_temporary(temporary_);

  for (PtrVector<CatalogAttribute, true>::const_iterator it = attr_vec_.begin();
       it != attr_vec_.end();
       ++it) {
    if (it.isNull()) {
      proto.add_attributes();
    } else {
      proto.add_attributes()->MergeFrom(it->getProto());
    }
  }

  proto.MutableExtension(serialization::CatalogRelation::default_layout)
      ->MergeFrom(getDefaultStorageBlockLayout().getDescription());

  {
    SpinSharedMutexSharedLock<false> lock(blocks_mutex_);
    for (const block_id block : blocks_) {
      proto.AddExtension(serialization::CatalogRelation::blocks, block);
    }
  }

  if (hasIndexScheme()) {
    proto.MutableExtension(serialization::CatalogRelation::index_scheme)->MergeFrom(index_scheme_->getProto());
  }

  // The partition scheme of the relation is stored in the protocol buffer format.
  if (hasPartitionScheme()) {
    proto.MutableExtension(serialization::CatalogRelation::partition_scheme)
        ->MergeFrom(partition_scheme_->getProto());
#ifdef QUICKSTEP_HAVE_LIBNUMA
    if (hasNUMAPlacementScheme()) {
      proto.MutableExtension(serialization::CatalogRelation::placement_scheme)
          ->MergeFrom(placement_scheme_->getProto());
    }
#endif
  }

  return proto;
}

void CatalogRelation::setPartitionScheme(PartitionScheme* partition_scheme) {
  DCHECK_EQ(0u, size_blocks());
  partition_scheme_.reset(partition_scheme);
}

void CatalogRelation::setDefaultStorageBlockLayout(StorageBlockLayout *default_layout) {
  DCHECK(&(default_layout->getRelation()) == this);
  default_layout_.reset(default_layout);
}

const StorageBlockLayout& CatalogRelation::getDefaultStorageBlockLayout() const {
  if (default_layout_ == nullptr) {
    default_layout_.reset(StorageBlockLayout::GenerateDefaultLayout(*this, isVariableLength()));
  }

  return *default_layout_;
}

}  // namespace quickstep
<|endoftext|>


<commit_before>// ------------------------------------------------------------------
// pion-platform: a C++ framework for building lightweight HTTP interfaces
// ------------------------------------------------------------------
// Copyright (C) 2007 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file COPYING or copy at http://www.boost.org/LICENSE_1_0.txt
//

#ifndef _MSC_VER
	#include <fcntl.h>
	#include <unistd.h>
	#include <sys/stat.h>
#endif

#ifdef PION_HAVE_SSL
	#include <openssl/ssl.h>
#endif

#include <iostream>
#include <boost/filesystem/operations.hpp>
#include "PlatformConfig.hpp"
#include "../../net/utils/ShutdownManager.hpp"

using namespace std;
using namespace pion;
using namespace pion::net;
using namespace pion::platform;
using namespace pion::server;

// some forward declarations of functions used by main()
void daemonize_server(void);
void argument_error(void);

/// main control function
int main (int argc, char *argv[])
{
	// get platform config file
	bool run_as_daemon = false;
	std::string platform_config_file("/etc/pion/platform.xml");
	for (int argnum=1; argnum < argc; ++argnum) {
		if (argv[argnum][0] == '-') {
			if (argv[argnum][1] == 'D') {
				run_as_daemon = true;
			} else if (argv[argnum][1] == 'c' && argv[argnum][2] == '\0' && argnum+1 < argc) {
				platform_config_file = boost::filesystem::system_complete(argv[++argnum]).normalize().file_string();
			} else if (strncmp(argv[argnum], "--version", 9) == 0) {
				std::cout << "pion version " << PION_VERSION << std::endl;
				return 0;
			} else {
				argument_error();
				return 1;
			}
		} else {
			argument_error();
			return 1;
		}
	}

	/// become a daemon if the -D option is given
	if (run_as_daemon)
		daemonize_server();

	// setup signal handler
#ifdef PION_WIN32
	SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
#else
	signal(SIGPIPE, SIG_IGN);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGINT, handle_signal);
	signal(SIGTERM, handle_signal);
#endif

	// initialize log system (use simple configuration)
	PionLogger pion_log(PION_GET_LOGGER("pion"));

	// This level might be overridden if there is a LogConfig file specified in the platform
	// configuration (and if using a logging library that supports logging configuration.)
	PION_LOG_SETLEVEL_INFO(pion_log);

	PION_LOG_CONFIG_BASIC;

#ifdef PION_HAVE_SSL
	// initialize the OpenSSL library
	SSL_library_init();
#endif

	PlatformConfig platform_cfg;
	try {
		// load the platform configuration
		platform_cfg.setConfigFile(platform_config_file);
		platform_cfg.openConfigFile();

		PION_LOG_INFO(pion_log, "Pion has started successfully (v" << PION_VERSION << ')');

		// wait for shutdown
		main_shutdown_manager.wait();

	} catch (std::exception& e) {
		PION_LOG_FATAL(pion_log, e.what());
	}

	PION_LOG_INFO(pion_log, "Pion is shutting down");

	return 0;
}

/// run server as a daemon
void daemonize_server(void)
{
#ifndef _MSC_VER
	// adopted from "Unix Daemon Server Programming"
	// http://www.enderunix.org/docs/eng/daemon.php

	// return early if already running as a daemon
	if(getppid()==1) return;

	// for out the process
	int i = fork();
	if (i<0) exit(1);	// error forking
	if (i>0) exit(0);	// exit if parent

	// child (daemon process) continues here after the fork...

	// obtain a new process group
	setsid();

	// close all descriptors
	for (i=getdtablesize();i>=0;--i) close(i);

	// bind stdio to /dev/null
	i=open("/dev/null",O_RDWR); dup(i); dup(i);

	// restrict file creation mode to 0750
	umask(027);
#endif
}

/// displays an error message if the arguments are invalid
void argument_error(void)
{
	std::cerr << "usage:   pion [-c SERVICE_CONFIG_FILE] [-D]" << std::endl;
}
<commit_msg>OpenSSL initializations and "applink" hack for Windows (trac #480)<commit_after>// ------------------------------------------------------------------
// pion-platform: a C++ framework for building lightweight HTTP interfaces
// ------------------------------------------------------------------
// Copyright (C) 2007 Atomic Labs, Inc.  (http://www.atomiclabs.com)
//
// Distributed under the Boost Software License, Version 1.0.
// See accompanying file COPYING or copy at http://www.boost.org/LICENSE_1_0.txt
//

#ifndef _MSC_VER
	#include <fcntl.h>
	#include <unistd.h>
	#include <sys/stat.h>
#endif

#ifdef PION_HAVE_SSL
	#include <openssl/ssl.h>
#ifdef _MSC_VER
	#include <openssl/applink.c>
#endif
#endif

#include <iostream>
#include <boost/filesystem/operations.hpp>
#include "PlatformConfig.hpp"
#include "../../net/utils/ShutdownManager.hpp"

using namespace std;
using namespace pion;
using namespace pion::net;
using namespace pion::platform;
using namespace pion::server;

// some forward declarations of functions used by main()
void daemonize_server(void);
void argument_error(void);

/// main control function
int main (int argc, char *argv[])
{
	// get platform config file
	bool run_as_daemon = false;
	std::string platform_config_file("/etc/pion/platform.xml");
	for (int argnum=1; argnum < argc; ++argnum) {
		if (argv[argnum][0] == '-') {
			if (argv[argnum][1] == 'D') {
				run_as_daemon = true;
			} else if (argv[argnum][1] == 'c' && argv[argnum][2] == '\0' && argnum+1 < argc) {
				platform_config_file = boost::filesystem::system_complete(argv[++argnum]).normalize().file_string();
			} else if (strncmp(argv[argnum], "--version", 9) == 0) {
				std::cout << "pion version " << PION_VERSION << std::endl;
				return 0;
			} else {
				argument_error();
				return 1;
			}
		} else {
			argument_error();
			return 1;
		}
	}

	/// become a daemon if the -D option is given
	if (run_as_daemon)
		daemonize_server();

	// setup signal handler
#ifdef PION_WIN32
	SetConsoleCtrlHandler(console_ctrl_handler, TRUE);
#else
	signal(SIGPIPE, SIG_IGN);
	signal(SIGCHLD, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGHUP, SIG_IGN);
	signal(SIGINT, handle_signal);
	signal(SIGTERM, handle_signal);
#endif

	// initialize log system (use simple configuration)
	PionLogger pion_log(PION_GET_LOGGER("pion"));

	// This level might be overridden if there is a LogConfig file specified in the platform
	// configuration (and if using a logging library that supports logging configuration.)
	PION_LOG_SETLEVEL_INFO(pion_log);

	PION_LOG_CONFIG_BASIC;

#ifdef PION_HAVE_SSL
	// initialize the OpenSSL library
	CRYPTO_malloc_init();
	SSL_library_init();
#endif

	PlatformConfig platform_cfg;
	try {
		// load the platform configuration
		platform_cfg.setConfigFile(platform_config_file);
		platform_cfg.openConfigFile();

		PION_LOG_INFO(pion_log, "Pion has started successfully (v" << PION_VERSION << ')');

		// wait for shutdown
		main_shutdown_manager.wait();

	} catch (std::exception& e) {
		PION_LOG_FATAL(pion_log, e.what());
	}

	PION_LOG_INFO(pion_log, "Pion is shutting down");

	return 0;
}

/// run server as a daemon
void daemonize_server(void)
{
#ifndef _MSC_VER
	// adopted from "Unix Daemon Server Programming"
	// http://www.enderunix.org/docs/eng/daemon.php

	// return early if already running as a daemon
	if(getppid()==1) return;

	// for out the process
	int i = fork();
	if (i<0) exit(1);	// error forking
	if (i>0) exit(0);	// exit if parent

	// child (daemon process) continues here after the fork...

	// obtain a new process group
	setsid();

	// close all descriptors
	for (i=getdtablesize();i>=0;--i) close(i);

	// bind stdio to /dev/null
	i=open("/dev/null",O_RDWR); dup(i); dup(i);

	// restrict file creation mode to 0750
	umask(027);
#endif
}

/// displays an error message if the arguments are invalid
void argument_error(void)
{
	std::cerr << "usage:   pion [-c SERVICE_CONFIG_FILE] [-D]" << std::endl;
}
<|endoftext|>


<commit_before>// Copyright (c) 2010 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.
//
// ChromeFrameHost implementation.
#include "ceee/ie/common/chrome_frame_host.h"

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "ceee/common/com_utils.h"
#include "ceee/common/process_utils_win.h"
#include "ceee/ie/common/ceee_module_util.h"
#include "chrome/browser/automation/extension_automation_constants.h"
#include "chrome/common/chrome_switches.h"

#include "toolband.h"  // NOLINT

namespace ext = extension_automation_constants;

_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_ =
    { CC_STDCALL, VT_EMPTY, 1, { VT_DISPATCH } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_long_ =
    { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_bstr_ =
    { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BSTR } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_variantptr_ =
    { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_bstr_i4_=
    { CC_STDCALL, VT_EMPTY, 2, { VT_BSTR, VT_I4 } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_bstrarray_=
    { CC_STDCALL, VT_EMPTY, 1, { VT_ARRAY | VT_BSTR } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_void_=
    { CC_STDCALL, VT_EMPTY, 0, { } };

// {AFA3E2CF-2C8E-4546-8CD0-A2D93759A4DE}
extern const GUID IID_IChromeFrameHost =
  { 0xafa3e2cf, 0x2c8e, 0x4546,
      { 0x8c, 0xd0, 0xa2, 0xd9, 0x37, 0x59, 0xa4, 0xde } };

ChromeFrameHost::ChromeFrameHost()
    : document_loaded_(false), origin_(ext::kAutomationOrigin) {
  LOG(INFO) << "Create ChromeFrameHost(" << this << ")";
}

ChromeFrameHost::~ChromeFrameHost() {
  LOG(INFO) << "Destroy ChromeFrameHost(" << this << ")";
}

HRESULT ChromeFrameHost::FinalConstruct() {
  return S_OK;
}

void ChromeFrameHost::FinalRelease() {
}

STDMETHODIMP ChromeFrameHost::GetWantsPrivileged(boolean* wants_privileged) {
  *wants_privileged = true;
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::GetChromeExtraArguments(BSTR* args) {
  DCHECK(args);

  // Extra arguments are passed on verbatim, so we add the -- prefix.
  CComBSTR str = "--";
  str.Append(switches::kEnableExperimentalExtensionApis);

  *args = str.Detach();
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::GetChromeProfileName(BSTR* profile_name) {
  return chrome_profile_name_.CopyTo(profile_name);
}

STDMETHODIMP ChromeFrameHost::GetExtensionApisToAutomate(
    BSTR* functions_enabled) {
  DCHECK(functions_enabled != NULL);
  HRESULT hr = S_FALSE;
  if (event_sink_ != NULL) {
    hr = event_sink_->OnCfGetExtensionApisToAutomate(functions_enabled);
#ifndef NDEBUG
    if (*functions_enabled != NULL) {
      // Only one chrome frame host is allowed to return a list of functions
      // to enable automation on, so make sure we are the one and only.
      std::wstring event_name(L"google-ceee-apiautomation!");

      DCHECK(chrome_profile_name_ != NULL);
      if (chrome_profile_name_ != NULL)
        event_name += chrome_profile_name_;

      std::replace(event_name.begin(), event_name.end(), '\\', '!');
      std::transform(
          event_name.begin(), event_name.end(), event_name.begin(), tolower);
      automating_extension_api_.Set(
          ::CreateEvent(NULL, TRUE, TRUE, event_name.c_str()));
      DWORD we = ::GetLastError();
      DCHECK(automating_extension_api_ != NULL &&
             we != ERROR_ALREADY_EXISTS &&
             we != ERROR_ACCESS_DENIED);
    }
#endif  // NDEBUG
  }
  return hr;
}

HRESULT ChromeFrameHost::Initialize() {
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::TearDown() {
  if (IsWindow()) {
    // TearDown the ActiveX host window.
    CAxWindow host(m_hWnd);
    CComPtr<IObjectWithSite> host_with_site;
    HRESULT hr = host.QueryHost(&host_with_site);
    if (SUCCEEDED(hr))
      host_with_site->SetSite(NULL);

    DestroyWindow();
  }

  if (chrome_frame_)
    ChromeFrameEvents::DispEventUnadvise(chrome_frame_);

  chrome_frame_.Release();
#ifndef NDEBUG
  automating_extension_api_.Close();
#endif
  return S_OK;
}

STDMETHODIMP_(void) ChromeFrameHost::SetEventSink(
    IChromeFrameHostEvents* event_sink) {
  event_sink_ = event_sink;
}

HRESULT ChromeFrameHost::InstallExtension(BSTR crx_path) {
  if (chrome_frame_) {
    return chrome_frame_->installExtension(crx_path);
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::LoadExtension(BSTR extension_dir) {
  if (chrome_frame_) {
    return chrome_frame_->installExtension(extension_dir);
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::GetEnabledExtensions() {
  if (chrome_frame_) {
    return chrome_frame_->getEnabledExtensions();
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::GetSessionId(int *session_id) {
  if (chrome_frame_) {
    CComQIPtr<IChromeFrameInternal> chrome_frame_internal_(chrome_frame_);
    if (chrome_frame_internal_)
      return chrome_frame_internal_->getSessionId(session_id);
    else
      return kInvalidChromeSessionId;
  }
  NOTREACHED();
  return E_UNEXPECTED;
}

void ChromeFrameHost::OnFinalMessage(HWND window) {
  GetUnknown()->Release();
}

HRESULT ChromeFrameHost::SetChildSite(IUnknown* child) {
  if (child == NULL)
    return E_POINTER;

  HRESULT hr = S_OK;
  CComPtr<IObjectWithSite> child_site;
  hr = child->QueryInterface(&child_site);
  if (SUCCEEDED(hr))
    hr = child_site->SetSite(GetUnknown());

  return hr;
}

LRESULT ChromeFrameHost::OnCreate(LPCREATESTRUCT lpCreateStruct) {
  // Grab a self-reference.
  GetUnknown()->AddRef();

  return 0;
}

HRESULT ChromeFrameHost::SetUrl(BSTR url) {
  HRESULT hr = chrome_frame_->put_src(url);
  DCHECK(SUCCEEDED(hr)) << "Failed to navigate Chrome Frame: " <<
    com::LogHr(hr);
  return hr;
}

STDMETHODIMP ChromeFrameHost::StartChromeFrame() {
  DCHECK(!IsWindow());

  // Create a message window to host our control.
  if (NULL == Create(HWND_MESSAGE))
    return E_FAIL;

  // Create a host window instance.
  CComPtr<IAxWinHostWindow> host;
  HRESULT hr = CreateActiveXHost(&host);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to create ActiveX host window: " << com::LogHr(hr);
    return hr;
  }

  // We're the site for the host window, this needs to be in place
  // before we attach ChromeFrame to the ActiveX control window, so
  // as to allow it to probe our service provider.
  hr = SetChildSite(host);
  DCHECK(SUCCEEDED(hr));

  // Create the chrome frame instance.
  hr = CreateChromeFrame(&chrome_frame_);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed create Chrome Frame: " << com::LogHr(hr);
    return hr;
  }

  // And attach it to our window. This causes the host to subclass
  // our window and attach itself to it.
  hr = host->AttachControl(chrome_frame_, m_hWnd);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to attach Chrome Frame to the host" << com::LogHr(hr);
    return hr;
  }

  // Hook up the chrome frame event listener.
  hr = ChromeFrameEvents::DispEventAdvise(chrome_frame_);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to hook up event sink: " << com::LogHr(hr);
    return hr;
  }

  return hr;
}

HRESULT ChromeFrameHost::CreateActiveXHost(IAxWinHostWindow** host) {
  return CAxHostWindow::CreateInstance(host);
}

HRESULT ChromeFrameHost::CreateChromeFrame(IChromeFrame** chrome_frame) {
  CComPtr<IChromeFrame> new_cf;
  HRESULT hr = new_cf.CoCreateInstance(L"ChromeTab.ChromeFrame");
  if (SUCCEEDED(hr))
    hr = new_cf.CopyTo(chrome_frame);

  return hr;
}

STDMETHODIMP ChromeFrameHost::PostMessage(BSTR message, BSTR target) {
  if (!document_loaded_) {
    PostedMessage posted_message = { message, target };
    posted_messages_.push_back(posted_message);
    return S_FALSE;
  }

  HRESULT hr = chrome_frame_->postPrivateMessage(message, origin_, target);

  return hr;
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfLoad(IDispatch* event) {
  DLOG(INFO) << "OnCfLoad";
  if (document_loaded_) {
    // If we were already loaded, our list should be empty.
    DCHECK(posted_messages_.empty());
    return;
  }
  document_loaded_ = true;

  // Flush all posted messages.
  PostedMessageList::iterator it(posted_messages_.begin());
  for (; it != posted_messages_.end(); ++it) {
    HRESULT hr = chrome_frame_->postPrivateMessage(it->message, origin_,
                                                   it->target);
    DCHECK(SUCCEEDED(hr)) << "postPrivateMessage failed with: " <<
        com::LogHr(hr);
  }
  posted_messages_.clear();
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfLoadError(IDispatch* event) {
  DLOG(ERROR) << "OnCfLoadError";
  DCHECK(false) << "OnCfLoadError";
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfExtensionReady(BSTR path,
                                                        int response) {
  DLOG(INFO) << "OnCfExtensionReady: " << path << ", " << response;
  // Early exit if there's no sink.
  if (event_sink_ == NULL)
    return;
  event_sink_->OnCfExtensionReady(path, response);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfGetEnabledExtensionsComplete(
    SAFEARRAY* extension_directories) {
  DLOG(INFO) << "OnCfGetEnabledExtensionsComplete";
  if (event_sink_)
    event_sink_->OnCfGetEnabledExtensionsComplete(extension_directories);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfChannelError() {
  DCHECK(false) << "OnCfChannelError means that Chrome has Crashed!";
  if (event_sink_)
    event_sink_->OnCfChannelError();
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfMessage(IDispatch* event) {
  DLOG(INFO) << "OnCfMessage";
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfReadyStateChanged(LONG state) {
  DLOG(INFO) << "OnCfReadyStateChanged(" << state << ")";
  if (event_sink_)
    event_sink_->OnCfReadyStateChanged(state);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfPrivateMessage(IDispatch* event,
                                                        BSTR target) {
  // Early exit if there's no sink.
  if (event_sink_ == NULL)
    return;

  // Make sure that the message has a "data" member and get it.  This should
  // be a JSON-encoded command to execute.
  CComDispatchDriver event_dispatch(event);

  CComVariant origin;
  HRESULT hr = event_dispatch.GetPropertyByName(L"origin", &origin);
  DCHECK(SUCCEEDED(hr) && origin.vt == VT_BSTR);
  if (FAILED(hr) || origin.vt != VT_BSTR) {
    NOTREACHED() << "No origin on event";
    return;
  }

  CComVariant data;
  hr = event_dispatch.GetPropertyByName(L"data", &data);
  DCHECK(SUCCEEDED(hr) && data.vt == VT_BSTR);
  if (FAILED(hr) || data.vt != VT_BSTR) {
    NOTREACHED() << "No data on event";
    return;
  }

  // Forward to the sink.
  event_sink_->OnCfPrivateMessage(V_BSTR(&data), V_BSTR(&origin), target);
}

STDMETHODIMP_(void) ChromeFrameHost::SetChromeProfileName(
    const wchar_t* chrome_profile_name) {
  chrome_profile_name_ = chrome_profile_name;
  DLOG(INFO) << "Assigned profile name " << chrome_profile_name_;
}
<commit_msg>Fixed return value of CFHost::getSession() BUG=none TEST=none<commit_after>// Copyright (c) 2010 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.
//
// ChromeFrameHost implementation.
#include "ceee/ie/common/chrome_frame_host.h"

#include <algorithm>
#include <vector>

#include "base/logging.h"
#include "ceee/common/com_utils.h"
#include "ceee/common/process_utils_win.h"
#include "ceee/ie/common/ceee_module_util.h"
#include "chrome/browser/automation/extension_automation_constants.h"
#include "chrome/common/chrome_switches.h"

#include "toolband.h"  // NOLINT

namespace ext = extension_automation_constants;

_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_ =
    { CC_STDCALL, VT_EMPTY, 1, { VT_DISPATCH } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_long_ =
    { CC_STDCALL, VT_EMPTY, 1, { VT_I4 } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_bstr_ =
    { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BSTR } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_idispatch_variantptr_ =
    { CC_STDCALL, VT_EMPTY, 2, { VT_DISPATCH, VT_BYREF | VT_VARIANT } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_bstr_i4_=
    { CC_STDCALL, VT_EMPTY, 2, { VT_BSTR, VT_I4 } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_bstrarray_=
    { CC_STDCALL, VT_EMPTY, 1, { VT_ARRAY | VT_BSTR } };
_ATL_FUNC_INFO ChromeFrameHost::handler_type_void_=
    { CC_STDCALL, VT_EMPTY, 0, { } };

// {AFA3E2CF-2C8E-4546-8CD0-A2D93759A4DE}
extern const GUID IID_IChromeFrameHost =
  { 0xafa3e2cf, 0x2c8e, 0x4546,
      { 0x8c, 0xd0, 0xa2, 0xd9, 0x37, 0x59, 0xa4, 0xde } };

ChromeFrameHost::ChromeFrameHost()
    : document_loaded_(false), origin_(ext::kAutomationOrigin) {
  LOG(INFO) << "Create ChromeFrameHost(" << this << ")";
}

ChromeFrameHost::~ChromeFrameHost() {
  LOG(INFO) << "Destroy ChromeFrameHost(" << this << ")";
}

HRESULT ChromeFrameHost::FinalConstruct() {
  return S_OK;
}

void ChromeFrameHost::FinalRelease() {
}

STDMETHODIMP ChromeFrameHost::GetWantsPrivileged(boolean* wants_privileged) {
  *wants_privileged = true;
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::GetChromeExtraArguments(BSTR* args) {
  DCHECK(args);

  // Extra arguments are passed on verbatim, so we add the -- prefix.
  CComBSTR str = "--";
  str.Append(switches::kEnableExperimentalExtensionApis);

  *args = str.Detach();
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::GetChromeProfileName(BSTR* profile_name) {
  return chrome_profile_name_.CopyTo(profile_name);
}

STDMETHODIMP ChromeFrameHost::GetExtensionApisToAutomate(
    BSTR* functions_enabled) {
  DCHECK(functions_enabled != NULL);
  HRESULT hr = S_FALSE;
  if (event_sink_ != NULL) {
    hr = event_sink_->OnCfGetExtensionApisToAutomate(functions_enabled);
#ifndef NDEBUG
    if (*functions_enabled != NULL) {
      // Only one chrome frame host is allowed to return a list of functions
      // to enable automation on, so make sure we are the one and only.
      std::wstring event_name(L"google-ceee-apiautomation!");

      DCHECK(chrome_profile_name_ != NULL);
      if (chrome_profile_name_ != NULL)
        event_name += chrome_profile_name_;

      std::replace(event_name.begin(), event_name.end(), '\\', '!');
      std::transform(
          event_name.begin(), event_name.end(), event_name.begin(), tolower);
      automating_extension_api_.Set(
          ::CreateEvent(NULL, TRUE, TRUE, event_name.c_str()));
      DWORD we = ::GetLastError();
      DCHECK(automating_extension_api_ != NULL &&
             we != ERROR_ALREADY_EXISTS &&
             we != ERROR_ACCESS_DENIED);
    }
#endif  // NDEBUG
  }
  return hr;
}

HRESULT ChromeFrameHost::Initialize() {
  return S_OK;
}

STDMETHODIMP ChromeFrameHost::TearDown() {
  if (IsWindow()) {
    // TearDown the ActiveX host window.
    CAxWindow host(m_hWnd);
    CComPtr<IObjectWithSite> host_with_site;
    HRESULT hr = host.QueryHost(&host_with_site);
    if (SUCCEEDED(hr))
      host_with_site->SetSite(NULL);

    DestroyWindow();
  }

  if (chrome_frame_)
    ChromeFrameEvents::DispEventUnadvise(chrome_frame_);

  chrome_frame_.Release();
#ifndef NDEBUG
  automating_extension_api_.Close();
#endif
  return S_OK;
}

STDMETHODIMP_(void) ChromeFrameHost::SetEventSink(
    IChromeFrameHostEvents* event_sink) {
  event_sink_ = event_sink;
}

HRESULT ChromeFrameHost::InstallExtension(BSTR crx_path) {
  if (chrome_frame_) {
    return chrome_frame_->installExtension(crx_path);
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::LoadExtension(BSTR extension_dir) {
  if (chrome_frame_) {
    return chrome_frame_->installExtension(extension_dir);
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::GetEnabledExtensions() {
  if (chrome_frame_) {
    return chrome_frame_->getEnabledExtensions();
  } else {
    NOTREACHED();
    return E_UNEXPECTED;
  }
}

HRESULT ChromeFrameHost::GetSessionId(int* session_id) {
  if (chrome_frame_) {
    CComQIPtr<IChromeFrameInternal> chrome_frame_internal_(chrome_frame_);
    if (chrome_frame_internal_) {
      return chrome_frame_internal_->getSessionId(session_id);
    } else {
      *session_id = kInvalidChromeSessionId;
      return S_OK;
    }
  }
  NOTREACHED();
  return E_UNEXPECTED;
}

void ChromeFrameHost::OnFinalMessage(HWND window) {
  GetUnknown()->Release();
}

HRESULT ChromeFrameHost::SetChildSite(IUnknown* child) {
  if (child == NULL)
    return E_POINTER;

  HRESULT hr = S_OK;
  CComPtr<IObjectWithSite> child_site;
  hr = child->QueryInterface(&child_site);
  if (SUCCEEDED(hr))
    hr = child_site->SetSite(GetUnknown());

  return hr;
}

LRESULT ChromeFrameHost::OnCreate(LPCREATESTRUCT lpCreateStruct) {
  // Grab a self-reference.
  GetUnknown()->AddRef();

  return 0;
}

HRESULT ChromeFrameHost::SetUrl(BSTR url) {
  HRESULT hr = chrome_frame_->put_src(url);
  DCHECK(SUCCEEDED(hr)) << "Failed to navigate Chrome Frame: " <<
    com::LogHr(hr);
  return hr;
}

STDMETHODIMP ChromeFrameHost::StartChromeFrame() {
  DCHECK(!IsWindow());

  // Create a message window to host our control.
  if (NULL == Create(HWND_MESSAGE))
    return E_FAIL;

  // Create a host window instance.
  CComPtr<IAxWinHostWindow> host;
  HRESULT hr = CreateActiveXHost(&host);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to create ActiveX host window: " << com::LogHr(hr);
    return hr;
  }

  // We're the site for the host window, this needs to be in place
  // before we attach ChromeFrame to the ActiveX control window, so
  // as to allow it to probe our service provider.
  hr = SetChildSite(host);
  DCHECK(SUCCEEDED(hr));

  // Create the chrome frame instance.
  hr = CreateChromeFrame(&chrome_frame_);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed create Chrome Frame: " << com::LogHr(hr);
    return hr;
  }

  // And attach it to our window. This causes the host to subclass
  // our window and attach itself to it.
  hr = host->AttachControl(chrome_frame_, m_hWnd);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to attach Chrome Frame to the host" << com::LogHr(hr);
    return hr;
  }

  // Hook up the chrome frame event listener.
  hr = ChromeFrameEvents::DispEventAdvise(chrome_frame_);
  if (FAILED(hr)) {
    LOG(ERROR) << "Failed to hook up event sink: " << com::LogHr(hr);
    return hr;
  }

  return hr;
}

HRESULT ChromeFrameHost::CreateActiveXHost(IAxWinHostWindow** host) {
  return CAxHostWindow::CreateInstance(host);
}

HRESULT ChromeFrameHost::CreateChromeFrame(IChromeFrame** chrome_frame) {
  CComPtr<IChromeFrame> new_cf;
  HRESULT hr = new_cf.CoCreateInstance(L"ChromeTab.ChromeFrame");
  if (SUCCEEDED(hr))
    hr = new_cf.CopyTo(chrome_frame);

  return hr;
}

STDMETHODIMP ChromeFrameHost::PostMessage(BSTR message, BSTR target) {
  if (!document_loaded_) {
    PostedMessage posted_message = { message, target };
    posted_messages_.push_back(posted_message);
    return S_FALSE;
  }

  HRESULT hr = chrome_frame_->postPrivateMessage(message, origin_, target);

  return hr;
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfLoad(IDispatch* event) {
  DLOG(INFO) << "OnCfLoad";
  if (document_loaded_) {
    // If we were already loaded, our list should be empty.
    DCHECK(posted_messages_.empty());
    return;
  }
  document_loaded_ = true;

  // Flush all posted messages.
  PostedMessageList::iterator it(posted_messages_.begin());
  for (; it != posted_messages_.end(); ++it) {
    HRESULT hr = chrome_frame_->postPrivateMessage(it->message, origin_,
                                                   it->target);
    DCHECK(SUCCEEDED(hr)) << "postPrivateMessage failed with: " <<
        com::LogHr(hr);
  }
  posted_messages_.clear();
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfLoadError(IDispatch* event) {
  DLOG(ERROR) << "OnCfLoadError";
  DCHECK(false) << "OnCfLoadError";
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfExtensionReady(BSTR path,
                                                        int response) {
  DLOG(INFO) << "OnCfExtensionReady: " << path << ", " << response;
  // Early exit if there's no sink.
  if (event_sink_ == NULL)
    return;
  event_sink_->OnCfExtensionReady(path, response);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfGetEnabledExtensionsComplete(
    SAFEARRAY* extension_directories) {
  DLOG(INFO) << "OnCfGetEnabledExtensionsComplete";
  if (event_sink_)
    event_sink_->OnCfGetEnabledExtensionsComplete(extension_directories);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfChannelError() {
  DCHECK(false) << "OnCfChannelError means that Chrome has Crashed!";
  if (event_sink_)
    event_sink_->OnCfChannelError();
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfMessage(IDispatch* event) {
  DLOG(INFO) << "OnCfMessage";
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfReadyStateChanged(LONG state) {
  DLOG(INFO) << "OnCfReadyStateChanged(" << state << ")";
  if (event_sink_)
    event_sink_->OnCfReadyStateChanged(state);
}

STDMETHODIMP_(void) ChromeFrameHost::OnCfPrivateMessage(IDispatch* event,
                                                        BSTR target) {
  // Early exit if there's no sink.
  if (event_sink_ == NULL)
    return;

  // Make sure that the message has a "data" member and get it.  This should
  // be a JSON-encoded command to execute.
  CComDispatchDriver event_dispatch(event);

  CComVariant origin;
  HRESULT hr = event_dispatch.GetPropertyByName(L"origin", &origin);
  DCHECK(SUCCEEDED(hr) && origin.vt == VT_BSTR);
  if (FAILED(hr) || origin.vt != VT_BSTR) {
    NOTREACHED() << "No origin on event";
    return;
  }

  CComVariant data;
  hr = event_dispatch.GetPropertyByName(L"data", &data);
  DCHECK(SUCCEEDED(hr) && data.vt == VT_BSTR);
  if (FAILED(hr) || data.vt != VT_BSTR) {
    NOTREACHED() << "No data on event";
    return;
  }

  // Forward to the sink.
  event_sink_->OnCfPrivateMessage(V_BSTR(&data), V_BSTR(&origin), target);
}

STDMETHODIMP_(void) ChromeFrameHost::SetChromeProfileName(
    const wchar_t* chrome_profile_name) {
  chrome_profile_name_ = chrome_profile_name;
  DLOG(INFO) << "Assigned profile name " << chrome_profile_name_;
}
<|endoftext|>


<commit_before>/*
    test_jobs.cpp

    This file is part of libkleopatra's test suite.
    Copyright (c) 2004 Klarlvdalens Datakonsult AB

    Libkleopatra is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License,
    version 2, as published by the Free Software Foundation.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <kleo/cryptobackendfactory.h>
#include <kleo/signjob.h>
#include <kleo/keylistjob.h>

#include <gpgmepp/key.h>
#include <gpgmepp/signingresult.h>
#include <gpgmepp/keylistresult.h>

#include <kdebug.h>
#include <assert.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <kapplication.h>

#include <memory>

static const char * protocol = 0;

static void testSign()
{
  const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ;
  assert( proto );

  kdDebug() << "Using protocol " << proto->name() << endl;

  std::vector<GpgME::Key> signingKeys;

  std::auto_ptr<Kleo::KeyListJob> listJob( proto->keyListJob( false, false, true ) ); // use validating keylisting
  if ( listJob.get() ) {
      // ##### Adjust this to your own identity
      listJob->exec( "faure@kde.org", true /*secret*/, signingKeys );
      assert( !signingKeys.empty() );
  } else {
      assert( 0 ); // job failed
  }

  Kleo::SignJob* job = proto->signJob( true, true );

  QCString cText = "Hallo Leute\n"; // like gpgme's t-sign.c
  QByteArray plainText;
  plainText.duplicate( cText.data(), cText.length() ); // hrmpf...
  kdDebug() << k_funcinfo << "plainText=" << plainText << endl;

  kdDebug() << k_funcinfo << " signing with " << signingKeys[0].primaryFingerprint() << endl;

  QByteArray signature;
  const GpgME::SigningResult res =
    job->exec( signingKeys, plainText, GpgME::Context::Clearsigned, signature );
  if ( res.error().isCanceled() ) {
    kdDebug() << "signing was canceled by user" << endl;
    return;
  }
  if ( res.error() ) {
    kdDebug() << "signing failed: " << res.error().asString() << endl;
    return;
  }
  kdDebug() << k_funcinfo << "signing resulted in signature=" << signature << endl;
}

int main( int argc, char** argv ) {
  protocol = "openpgp";
  if ( argc == 2 ) {
    protocol = argv[1];
    argc = 1; // hide from KDE
  }
  KAboutData aboutData( "test_jobs", "Signing Job Test", "0.1" );
  KCmdLineArgs::init( argc, argv, &aboutData );
  KApplication app;

  testSign();
}
<commit_msg>compile, there is no operator<<( k(n)dbgstream, QByteArray ) and the implicit casts available make the call ambiguous.<commit_after>/*
    test_jobs.cpp

    This file is part of libkleopatra's test suite.
    Copyright (c) 2004 Klarlvdalens Datakonsult AB

    Libkleopatra is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License,
    version 2, as published by the Free Software Foundation.

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

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

    In addition, as a special exception, the copyright holders give
    permission to link the code of this program with any edition of
    the Qt library by Trolltech AS, Norway (or with modified versions
    of Qt that use the same license as Qt), and distribute linked
    combinations including the two.  You must obey the GNU General
    Public License in all respects for all of the code used other than
    Qt.  If you modify this file, you may extend this exception to
    your version of the file, but you are not obligated to do so.  If
    you do not wish to do so, delete this exception statement from
    your version.
*/

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <kleo/cryptobackendfactory.h>
#include <kleo/signjob.h>
#include <kleo/keylistjob.h>

#include <gpgmepp/key.h>
#include <gpgmepp/signingresult.h>
#include <gpgmepp/keylistresult.h>

#include <kdebug.h>
#include <assert.h>
#include <kaboutdata.h>
#include <kcmdlineargs.h>
#include <kapplication.h>

#include <memory>

static const char * protocol = 0;

static void testSign()
{
  const Kleo::CryptoBackend::Protocol * proto = protocol == "openpgp" ? Kleo::CryptoBackendFactory::instance()->openpgp() : Kleo::CryptoBackendFactory::instance()->smime() ;
  assert( proto );

  kdDebug() << "Using protocol " << proto->name() << endl;

  std::vector<GpgME::Key> signingKeys;

  std::auto_ptr<Kleo::KeyListJob> listJob( proto->keyListJob( false, false, true ) ); // use validating keylisting
  if ( listJob.get() ) {
      // ##### Adjust this to your own identity
      listJob->exec( "faure@kde.org", true /*secret*/, signingKeys );
      assert( !signingKeys.empty() );
  } else {
      assert( 0 ); // job failed
  }

  Kleo::SignJob* job = proto->signJob( true, true );

  QCString cText = "Hallo Leute\n"; // like gpgme's t-sign.c
  QByteArray plainText;
  plainText.duplicate( cText.data(), cText.length() ); // hrmpf...
  kdDebug() << k_funcinfo << "plainText=" << cText.data() << endl;

  kdDebug() << k_funcinfo << " signing with " << signingKeys[0].primaryFingerprint() << endl;

  QByteArray signature;
  const GpgME::SigningResult res =
    job->exec( signingKeys, plainText, GpgME::Context::Clearsigned, signature );
  if ( res.error().isCanceled() ) {
    kdDebug() << "signing was canceled by user" << endl;
    return;
  }
  if ( res.error() ) {
    kdDebug() << "signing failed: " << res.error().asString() << endl;
    return;
  }
  kdDebug() << k_funcinfo << "signing resulted in signature="
	    << QCString( signature.data(), signature.size() + 1 ) << endl;
}

int main( int argc, char** argv ) {
  protocol = "openpgp";
  if ( argc == 2 ) {
    protocol = argv[1];
    argc = 1; // hide from KDE
  }
  KAboutData aboutData( "test_jobs", "Signing Job Test", "0.1" );
  KCmdLineArgs::init( argc, argv, &aboutData );
  KApplication app;

  testSign();
}
<|endoftext|>


<commit_before>/***********************************************************************
    created:    25/1/2006
    author:     Andrew Zabolotny

    purpose:    Implementation of the DefaultLogger class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/DefaultLogger.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/System.h"
#ifdef __ANDROID__
#   include <android/log.h>
#endif
#include <ctime>
#include <iomanip>

namespace CEGUI
{
//----------------------------------------------------------------------------//
DefaultLogger::DefaultLogger(void)
   : d_caching(true)
{
    // create log header
    logEvent("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+");
    logEvent("+                     Crazy Eddie's GUI System - Event log                    +");
    logEvent("+                          (http://www.cegui.org.uk/)                         +");
    logEvent("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    logEvent("CEGUI::Logger singleton created. " + String(addr_buff));
}

//----------------------------------------------------------------------------//
DefaultLogger::~DefaultLogger(void)
{
    if (d_ostream.is_open())
    {
        char addr_buff[32];
        sprintf(addr_buff, "(%p)", static_cast<void*>(this));
        logEvent("CEGUI::Logger singleton destroyed. " + String(addr_buff));
        d_ostream.close();
    }
}

//----------------------------------------------------------------------------//
void DefaultLogger::logEvent(const String& message,
                             LoggingLevel level /* = Standard */)
{
    using namespace std;

    time_t et;
    time(&et);
    tm* etm = localtime(&et);

    if (!etm)
        return;

    // clear sting stream
    d_workstream.str("");

    // write date
    d_workstream << setfill('0') << setw(2) << etm->tm_mday << '/' <<
    setfill('0') << setw(2) << 1 + etm->tm_mon << '/' <<
    setw(4) << (1900 + etm->tm_year) << ' ';

    // write time
    d_workstream << setfill('0') << setw(2) << etm->tm_hour << ':' <<
    setfill('0') << setw(2) << etm->tm_min << ':' <<
    setfill('0') << setw(2) << etm->tm_sec << ' ';

    // write event type code
    switch(level)
    {
    case Errors:
        d_workstream << "(Error)\t";
        break;

    case Warnings:
        d_workstream << "(Warn)\t";
        break;

    case Standard:
        d_workstream << "(Std) \t";
        break;

    case Informative:
        d_workstream << "(Info) \t";
        break;

    case Insane:
        d_workstream << "(Insan)\t";
        break;

    default:
        d_workstream << "(Unkwn)\t";
        break;
    }

    d_workstream << message << endl;

    if (d_caching)
    {
        d_cache.push_back(std::make_pair(d_workstream.str().c_str(), level));
    }
    if (d_level >= level)
    {
        if (!d_caching)
        {
            // write message
            d_ostream << d_workstream.str();
            // ensure new event is written to the file, rather than just being
            // buffered.
            d_ostream.flush();
        }
        #ifdef __ANDROID__
            int priority(ANDROID_LOG_UNKNOWN);
            switch (level)
            {
            case Errors:
                priority = ANDROID_LOG_ERROR;
                break;
            case Warnings:
                priority = ANDROID_LOG_WARN;
                break;
            case Standard:
                priority = ANDROID_LOG_INFO;
                break;
            case Informative:
                priority = ANDROID_LOG_DEBUG;
                break;
            case Insane:
            default:
                priority = ANDROID_LOG_VERBOSE;
                break;
            }
            __android_log_write(priority, "CEGUI_log", d_workstream.str().c_str());
        #endif
    }
}

//----------------------------------------------------------------------------//
void DefaultLogger::setLogFilename(const String& filename, bool append)
{
    // close current log file (if any)
    if (d_ostream.is_open())
        d_ostream.close();

#   if defined(_MSC_VER)
    d_ostream.open(System::getStringTranscoder().stringToStdWString(filename).c_str(),
                   std::ios_base::out |
                   (append ? std::ios_base::app : std::ios_base::trunc));
#   else
    d_ostream.open(filename.c_str(),
                   std::ios_base::out |
                   (append ? std::ios_base::app : std::ios_base::trunc));
#   endif

    if (!d_ostream)
        throw FileIOException(
            "Failed to open file '" + filename + "' for writing");

    // initialise width for date & time alignment.
    d_ostream.width(2);

    // write out cached log strings.
    if (d_caching)
    {
        d_caching = false;

        Cache::iterator iter = d_cache.begin();

        while (iter != d_cache.end())
        {
            if (d_level >= (*iter).second)
            {
                // write message
                d_ostream << (*iter).first;
                // ensure new event is written to the file, rather than just
                // being buffered.
                d_ostream.flush();
            }

            ++iter;
        }

        d_cache.clear();
    }
}

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

}

<commit_msg>MOD: Minor log output change<commit_after>/***********************************************************************
    created:    25/1/2006
    author:     Andrew Zabolotny

    purpose:    Implementation of the DefaultLogger class
*************************************************************************/
/***************************************************************************
 *   Copyright (C) 2004 - 2012 Paul D Turner & The CEGUI Development Team
 *
 *   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 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 "CEGUI/DefaultLogger.h"
#include "CEGUI/Exceptions.h"
#include "CEGUI/System.h"
#ifdef __ANDROID__
#   include <android/log.h>
#endif
#include <ctime>
#include <iomanip>

namespace CEGUI
{
//----------------------------------------------------------------------------//
DefaultLogger::DefaultLogger(void)
   : d_caching(true)
{
    // create log header
    logEvent("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+");
    logEvent("+                     Crazy Eddie's GUI System - Event log                    +");
    logEvent("+                          (http://www.cegui.org.uk/)                         +");
    logEvent("+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+\n");
    char addr_buff[32];
    sprintf(addr_buff, "(%p)", static_cast<void*>(this));
    logEvent("CEGUI::Logger Singleton created. " + String(addr_buff));
}

//----------------------------------------------------------------------------//
DefaultLogger::~DefaultLogger(void)
{
    if (d_ostream.is_open())
    {
        char addr_buff[32];
        sprintf(addr_buff, "(%p)", static_cast<void*>(this));
        logEvent("CEGUI::Logger singleton destroyed. " + String(addr_buff));
        d_ostream.close();
    }
}

//----------------------------------------------------------------------------//
void DefaultLogger::logEvent(const String& message,
                             LoggingLevel level /* = Standard */)
{
    using namespace std;

    time_t et;
    time(&et);
    tm* etm = localtime(&et);

    if (!etm)
        return;

    // clear sting stream
    d_workstream.str("");

    // write date
    d_workstream << setfill('0') << setw(2) << etm->tm_mday << '/' <<
    setfill('0') << setw(2) << 1 + etm->tm_mon << '/' <<
    setw(4) << (1900 + etm->tm_year) << ' ';

    // write time
    d_workstream << setfill('0') << setw(2) << etm->tm_hour << ':' <<
    setfill('0') << setw(2) << etm->tm_min << ':' <<
    setfill('0') << setw(2) << etm->tm_sec << ' ';

    // write event type code
    switch(level)
    {
    case Errors:
        d_workstream << "(Error)\t";
        break;

    case Warnings:
        d_workstream << "(Warn)\t";
        break;

    case Standard:
        d_workstream << "(Std) \t";
        break;

    case Informative:
        d_workstream << "(Info) \t";
        break;

    case Insane:
        d_workstream << "(Insan)\t";
        break;

    default:
        d_workstream << "(Unkwn)\t";
        break;
    }

    d_workstream << message << endl;

    if (d_caching)
    {
        d_cache.push_back(std::make_pair(d_workstream.str().c_str(), level));
    }
    if (d_level >= level)
    {
        if (!d_caching)
        {
            // write message
            d_ostream << d_workstream.str();
            // ensure new event is written to the file, rather than just being
            // buffered.
            d_ostream.flush();
        }
        #ifdef __ANDROID__
            int priority(ANDROID_LOG_UNKNOWN);
            switch (level)
            {
            case Errors:
                priority = ANDROID_LOG_ERROR;
                break;
            case Warnings:
                priority = ANDROID_LOG_WARN;
                break;
            case Standard:
                priority = ANDROID_LOG_INFO;
                break;
            case Informative:
                priority = ANDROID_LOG_DEBUG;
                break;
            case Insane:
            default:
                priority = ANDROID_LOG_VERBOSE;
                break;
            }
            __android_log_write(priority, "CEGUI_log", d_workstream.str().c_str());
        #endif
    }
}

//----------------------------------------------------------------------------//
void DefaultLogger::setLogFilename(const String& filename, bool append)
{
    // close current log file (if any)
    if (d_ostream.is_open())
        d_ostream.close();

#   if defined(_MSC_VER)
    d_ostream.open(System::getStringTranscoder().stringToStdWString(filename).c_str(),
                   std::ios_base::out |
                   (append ? std::ios_base::app : std::ios_base::trunc));
#   else
    d_ostream.open(filename.c_str(),
                   std::ios_base::out |
                   (append ? std::ios_base::app : std::ios_base::trunc));
#   endif

    if (!d_ostream)
        throw FileIOException(
            "Failed to open file '" + filename + "' for writing");

    // initialise width for date & time alignment.
    d_ostream.width(2);

    // write out cached log strings.
    if (d_caching)
    {
        d_caching = false;

        Cache::iterator iter = d_cache.begin();

        while (iter != d_cache.end())
        {
            if (d_level >= (*iter).second)
            {
                // write message
                d_ostream << (*iter).first;
                // ensure new event is written to the file, rather than just
                // being buffered.
                d_ostream.flush();
            }

            ++iter;
        }

        d_cache.clear();
    }
}

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

}

<|endoftext|>