<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2018 Couchbase, Inc
 *
 *   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.
 */

/*
 * Unit tests for DCP which connecting a DCP Producer to a DCP Consumer.
 */

#include <memcached/protocol_binary.h>
#include <programs/engine_testapp/mock_server.h>
#include <tests/mock/mock_checkpoint_manager.h>
#include <tests/mock/mock_dcp_consumer.h>
#include <tests/mock/mock_dcp_producer.h>
#include <tests/mock/mock_stream.h>
#include <tests/mock/mock_synchronous_ep_engine.h>

#include "checkpoint_manager.h"
#include "dcp/response.h"
#include "evp_store_single_threaded_test.h"
#include "test_helpers.h"

/**
 * Test fixture which creates two ep-engine (bucket) instances, using one
 * as a source for DCP replication and the second as the destination.
 */
class DCPLoopbackStreamTest : public SingleThreadedKVBucketTest {
protected:
    void SetUp() override {
        SingleThreadedKVBucketTest::SetUp();
    }

    ENGINE_ERROR_CODE getInternalHelper(const DocKey& key) {
        return getInternal(key,
                           vbid,
                           cookie,
                           vbucket_state_t::vbucket_state_active,
                           get_options_t::NONE)
                .getStatus();
    }

    void setupProducer(EnableExpiryOutput enableExpiryOutput,
                       uint32_t exp_time = 0) {
        // Setup the source (active) Bucket.
        EXPECT_EQ(ENGINE_SUCCESS,
                  engine->getKVBucket()->setVBucketState(vbid,
                                                         vbucket_state_active));

        // Add some items to the source Bucket.
        auto key1 = makeStoredDocKey("key1");
        auto key2 = makeStoredDocKey("key2");
        auto key3 = makeStoredDocKey("key3");
        store_item(vbid, key1, "value", exp_time);
        store_item(vbid, key2, "value", exp_time);
        store_item(vbid, key3, "value", exp_time);

        // Create the Dcp producer.
        producer = SingleThreadedKVBucketTest::createDcpProducer(
                cookie,
                IncludeDeleteTime::No);
        producer->scheduleCheckpointProcessorTask();

        // Setup conditions for expirations
        auto expectedGetOutcome = ENGINE_SUCCESS;
        if (enableExpiryOutput == EnableExpiryOutput::Yes) {
            producer->setDCPExpiry(true);
            expectedGetOutcome = ENGINE_KEY_ENOENT;
        }
        TimeTraveller t(1080);
        // Trigger expiries on a get, or just check that the key exists
        EXPECT_EQ(expectedGetOutcome, getInternalHelper(key1));
        EXPECT_EQ(expectedGetOutcome, getInternalHelper(key2));
        EXPECT_EQ(expectedGetOutcome, getInternalHelper(key3));

        auto& sourceVb = *engine->getVBucket(vbid);
        producer->mockActiveStreamRequest(consumerStream->getFlags(),
                                          consumerStream->getOpaque(),
                                          sourceVb,
                                          consumerStream->getStartSeqno(),
                                          consumerStream->getEndSeqno(),
                                          consumerStream->getVBucketUUID(),
                                          consumerStream->getSnapStartSeqno(),
                                          consumerStream->getSnapEndSeqno());
        producerStream = dynamic_cast<MockActiveStream*>(
                producer->findStream(vbid).get());

        ASSERT_EQ(2, static_cast<MockCheckpointManager*>(
                sourceVb.checkpointManager.get())
                ->getNumOfCursors())
                << "Should have both persistence and DCP producer cursor on "
                   "source "
                   "VB";

        // Creating a producer will schedule one
        // ActiveStreamCheckpointProcessorTask
        // that task though sleeps forever, so won't run until woken.
        ASSERT_EQ(1, getLpAuxQ()->getFutureQueueSize());
    }

    void setupConsumer(uint32_t flags) {
        // In addition to the initial engine which is created; we also need
        // to create a second bucket instance for the destination (replica)
        // vBucket.
        std::string config = config_string;
        if (config.size() > 0) {
            config += ";";
        }
        config += "dbname=" + std::string(test_dbname) + "-replica";
        replicaEngine = SynchronousEPEngine::build(config);

        // Setup destination (replica) Bucket.
        EXPECT_EQ(ENGINE_SUCCESS,
                  replicaEngine->getKVBucket()->setVBucketState(
                          vbid, vbucket_state_replica));

        // Setup the consumer.
        consumer = std::make_shared<MockDcpConsumer>(
                *replicaEngine, cookie, "test_consumer");
        EXPECT_EQ(ENGINE_SUCCESS,
                  consumer->addStream(
                          /*opaque*/ 0, vbid, flags));
        consumerStream = consumer->getVbucketStream(vbid).get();

        // Need to discard the first message from the consumerStream (the
        // StreamRequest), as we'll manually set that up in the producer.
        {
            std::unique_ptr<DcpResponse> streamRequest(consumerStream->next());
            EXPECT_NE(nullptr, streamRequest);
            EXPECT_EQ(DcpResponse::Event::StreamReq, streamRequest->getEvent());
        }
    }

    void TearDown() override {
        producer->cancelCheckpointCreatorTask();
        producer->closeAllStreams();
        producer.reset();

        consumer->closeAllStreams();
        consumer.reset();
        shutdownAndPurgeTasks(replicaEngine.get());
        destroy_mock_cookie(cookie);
        cookie = nullptr;
        replicaEngine.reset();
        SingleThreadedKVBucketTest::TearDown();
    }

    TaskQueue* getLpAuxQ() const {
        auto* task_executor = reinterpret_cast<SingleThreadedExecutorPool*>(
                ExecutorPool::get());
        return task_executor->getLpTaskQ()[AUXIO_TASK_IDX];
    }

    std::unique_ptr<DcpResponse> getNextProducerMsg(MockActiveStream* stream) {
        std::unique_ptr<DcpResponse> producerMsg(stream->next());
        if (!producerMsg) {
            EXPECT_EQ(1, getLpAuxQ()->getFutureQueueSize())
                    << "Expected to have ActiveStreamCheckpointProcessorTask "
                       "in future queue after null producerMsg";
            stream->nextCheckpointItemTask();
            EXPECT_GT(stream->getItemsRemaining(), 0)
                    << "Expected some items ready after calling "
                       "nextCheckpointItemTask()";
            return getNextProducerMsg(stream);
        }
        return producerMsg;
    }

    void readNextConsumerMsgAndSendToProducer(ActiveStream& producerStream,
                                              PassiveStream& consumerStream);

    void takeoverTest(EnableExpiryOutput enableExpiryOutput);

    SynchronousEPEngineUniquePtr replicaEngine;
    std::shared_ptr<MockDcpConsumer> consumer;
    // Non-owning ptr to consumer stream (owned by consumer).
    PassiveStream* consumerStream;

    std::shared_ptr<MockDcpProducer> producer;

    // Non-owning ptr to producer stream (owned by producer).
    MockActiveStream* producerStream;
};

void DCPLoopbackStreamTest::readNextConsumerMsgAndSendToProducer(
        ActiveStream& producerStream, PassiveStream& consumerStream) {
    std::unique_ptr<DcpResponse> consumerMsg(consumerStream.next());

    // Pass the consumer's message to the producer.
    if (consumerMsg) {
        switch (consumerMsg->getEvent()) {
        case DcpResponse::Event::SnapshotMarker:
            producerStream.snapshotMarkerAckReceived();
            break;
        case DcpResponse::Event::SetVbucket:
            producerStream.setVBucketStateAckRecieved();
            break;
        default:
            FAIL();
        }
    }
}

/**
 * Test the behaviour of a Takeover stream between a DcpProducer and
 * DcpConsumer.
 *
 * Creates a Producer and Consumer; along with a single Active -> Passive
 * stream, then makes a streamRequest (simulating what ns_server normally does).
 * Then loops; reading messages from the producer and passing them to the
 * consumer, and reading responses from the consumer and passing to the
 * producer. Test finishes when the PassiveStream is set to Dead - at that point
 * the vBucket should be active on the destination; and dead on the source.
 */
void DCPLoopbackStreamTest::takeoverTest(
        EnableExpiryOutput enableExpiryOutput) {
    uint32_t exp_time = 0;
    if (enableExpiryOutput == EnableExpiryOutput::Yes) {
        exp_time = time(NULL) + 256;
    }

    // Note: the order matters.
    //     First, we setup the Consumer with the given flags and we discard the
    //     StreamRequest message from the Consumer::readyQ.
    //     Then, we simulate the Producer receiving the StreamRequest just
    //     by creating the Producer with the Consumer's flags
    setupConsumer(DCP_ADD_STREAM_FLAG_TAKEOVER);
    setupProducer(enableExpiryOutput, exp_time);

    // Both streams created. Check state is as expected.
    ASSERT_TRUE(producerStream->isTakeoverSend())
            << "Producer stream state should have transitioned to "
               "TakeoverSend";

    while (true) {
        auto producerMsg = getNextProducerMsg(producerStream);
        ASSERT_TRUE(producerMsg);

        // Cannot pass mutation/deletion directly to the consumer as the object
        // is different
        if (producerMsg->getEvent() == DcpResponse::Event::Mutation ||
            producerMsg->getEvent() == DcpResponse::Event::Deletion ||
            producerMsg->getEvent() == DcpResponse::Event::Expiration) {
            producerMsg = std::make_unique<MutationConsumerMessage>(
                    *static_cast<MutationResponse*>(producerMsg.get()));
        }

        // Pass the message onto the consumer.
        EXPECT_EQ(ENGINE_SUCCESS,
                  consumerStream->messageReceived(std::move(producerMsg)));

        // Get the next message from the consumer; and pass to the producer.
        readNextConsumerMsgAndSendToProducer(*producerStream, *consumerStream);

        // Check consumer stream state - drop reflecting messages when
        // stream goes dead.
        if (!consumerStream->isActive()) {
            break;
        }
    }

    auto* sourceVb = engine->getVBucket(vbid).get();
    EXPECT_EQ(vbucket_state_dead, sourceVb->getState())
            << "Expected producer vBucket to be dead once stream "
               "transitions to dead.";

    auto* destVb = replicaEngine->getVBucket(vbid).get();
    EXPECT_EQ(vbucket_state_active, destVb->getState())
            << "Expected consumer vBucket to be active once stream "
               "transitions to dead.";

    // Check final state of items
    auto num_left = 3, expired = 0;
    auto expectedOutcome = ENGINE_SUCCESS;
    if (enableExpiryOutput == EnableExpiryOutput::Yes) {
        num_left = 0, expired = 3;
        expectedOutcome = ENGINE_KEY_ENOENT;
    }
    EXPECT_EQ(num_left, sourceVb->getNumItems());
    EXPECT_EQ(num_left, destVb->getNumItems());
    EXPECT_EQ(expired, sourceVb->numExpiredItems);
    // numExpiredItems is a stat for recording how many items have been flipped
    // from active to expired on a vbucket, so does not get transferred during
    // a takeover.

    auto key1 = makeStoredDocKey("key1");
    EXPECT_EQ(expectedOutcome, getInternalHelper(key1));
}

TEST_F(DCPLoopbackStreamTest, Takeover) {
    takeoverTest(EnableExpiryOutput::No);
}

TEST_F(DCPLoopbackStreamTest, TakeoverWithExpiry) {
    takeoverTest(EnableExpiryOutput::Yes);
}
<commit_msg>Refactor DCPLoopbackStreamTest for use with additional tests<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2018 Couchbase, Inc
 *
 *   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.
 */

/*
 * Unit tests for DCP which connecting a DCP Producer to a DCP Consumer.
 */

#include <memcached/protocol_binary.h>
#include <platform/dirutils.h>
#include <programs/engine_testapp/mock_server.h>
#include <tests/mock/mock_checkpoint_manager.h>
#include <tests/mock/mock_dcp_consumer.h>
#include <tests/mock/mock_dcp_producer.h>
#include <tests/mock/mock_stream.h>
#include <tests/mock/mock_synchronous_ep_engine.h>

#include "checkpoint_manager.h"
#include "dcp/response.h"
#include "evp_store_single_threaded_test.h"
#include "test_helpers.h"

/**
 * Test fixture which creates two ep-engine (bucket) instances, using one
 * as a source for DCP replication and the second as the destination.
 */
class DCPLoopbackStreamTest : public SingleThreadedKVBucketTest {
protected:
    void SetUp() override {
        SingleThreadedKVBucketTest::SetUp();

        // Paranoia - remove any previous replica disk files.
        try {
            cb::io::rmrf(std::string(test_dbname) + "-replica");
        } catch (std::system_error& e) {
            if (e.code() != std::error_code(ENOENT, std::system_category())) {
                throw e;
            }
        }

        ASSERT_EQ(ENGINE_SUCCESS,
                  engine->getKVBucket()->setVBucketState(
                          vbid,
                          vbucket_state_active,
                          {{"topology",
                            nlohmann::json::array({{"active", "replica"}})}}));
    }

    ENGINE_ERROR_CODE getInternalHelper(const DocKey& key) {
        return getInternal(key,
                           vbid,
                           cookie,
                           vbucket_state_t::vbucket_state_active,
                           get_options_t::NONE)
                .getStatus();
    }

    void setupProducer(EnableExpiryOutput enableExpiryOutput) {
        // Create the Dcp producer.
        producer = SingleThreadedKVBucketTest::createDcpProducer(
                cookie,
                IncludeDeleteTime::No);
        producer->scheduleCheckpointProcessorTask();
        if (enableExpiryOutput == EnableExpiryOutput::Yes) {
            producer->setDCPExpiry(true);
        }

        auto& sourceVb = *engine->getVBucket(vbid);
        producer->mockActiveStreamRequest(consumerStream->getFlags(),
                                          consumerStream->getOpaque(),
                                          sourceVb,
                                          consumerStream->getStartSeqno(),
                                          consumerStream->getEndSeqno(),
                                          consumerStream->getVBucketUUID(),
                                          consumerStream->getSnapStartSeqno(),
                                          consumerStream->getSnapEndSeqno());
        producerStream = dynamic_cast<MockActiveStream*>(
                producer->findStream(vbid).get());

        ASSERT_EQ(2,
                  static_cast<MockCheckpointManager*>(
                          sourceVb.checkpointManager.get())
                          ->getNumOfCursors())
                << "Should have both persistence and DCP producer cursor on "
                   "source VB";

        // Creating a producer will schedule one
        // ActiveStreamCheckpointProcessorTask
        // that task though sleeps forever, so won't run until woken.
        ASSERT_EQ(1, getLpAuxQ()->getFutureQueueSize());
    }

    void setupConsumer(uint32_t flags) {
        // In addition to the initial engine which is created; we also need
        // to create a second bucket instance for the destination (replica)
        // vBucket.
        std::string config = config_string;
        if (config.size() > 0) {
            config += ";";
        }
        config += "dbname=" + std::string(test_dbname) + "-replica";
        replicaEngine = SynchronousEPEngine::build(config);

        // Setup destination (replica) Bucket.
        EXPECT_EQ(ENGINE_SUCCESS,
                  replicaEngine->getKVBucket()->setVBucketState(
                          vbid, vbucket_state_replica));

        // Setup the consumer.
        consumer = std::make_shared<MockDcpConsumer>(
                *replicaEngine, cookie, "test_consumer");
        EXPECT_EQ(ENGINE_SUCCESS,
                  consumer->addStream(
                          /*opaque*/ 0, vbid, flags));
        consumerStream = consumer->getVbucketStream(vbid).get();

        // Need to discard the first message from the consumerStream (the
        // StreamRequest), as we'll manually set that up in the producer.
        {
            std::unique_ptr<DcpResponse> streamRequest(consumerStream->next());
            EXPECT_NE(nullptr, streamRequest);
            EXPECT_EQ(DcpResponse::Event::StreamReq, streamRequest->getEvent());
        }
    }

    void TearDown() override {
        producer->cancelCheckpointCreatorTask();
        producer->closeAllStreams();
        producer.reset();

        consumer->closeAllStreams();
        consumer.reset();
        shutdownAndPurgeTasks(replicaEngine.get());
        destroy_mock_cookie(cookie);
        cookie = nullptr;
        replicaEngine.reset();
        SingleThreadedKVBucketTest::TearDown();
    }

    TaskQueue* getLpAuxQ() const {
        auto* task_executor = reinterpret_cast<SingleThreadedExecutorPool*>(
                ExecutorPool::get());
        return task_executor->getLpTaskQ()[AUXIO_TASK_IDX];
    }

    std::unique_ptr<DcpResponse> getNextProducerMsg(MockActiveStream* stream) {
        std::unique_ptr<DcpResponse> producerMsg(stream->next());
        if (!producerMsg) {
            EXPECT_EQ(1, getLpAuxQ()->getFutureQueueSize())
                    << "Expected to have ActiveStreamCheckpointProcessorTask "
                       "in future queue after null producerMsg";
            stream->nextCheckpointItemTask();
            EXPECT_GT(stream->getItemsRemaining(), 0)
                    << "Expected some items ready after calling "
                       "nextCheckpointItemTask()";
            return getNextProducerMsg(stream);
        }

        // Cannot pass mutation/deletion directly to the consumer as the object
        // is different
        if (producerMsg->getEvent() == DcpResponse::Event::Mutation ||
            producerMsg->getEvent() == DcpResponse::Event::Deletion ||
            producerMsg->getEvent() == DcpResponse::Event::Expiration ||
            producerMsg->getEvent() == DcpResponse::Event::Prepare) {
            producerMsg = std::make_unique<MutationConsumerMessage>(
                    *static_cast<MutationResponse*>(producerMsg.get()));
        }

        return producerMsg;
    }

    void readNextConsumerMsgAndSendToProducer(ActiveStream& producerStream,
                                              PassiveStream& consumerStream);

    void takeoverTest(EnableExpiryOutput enableExpiryOutput);

    SynchronousEPEngineUniquePtr replicaEngine;
    std::shared_ptr<MockDcpConsumer> consumer;
    // Non-owning ptr to consumer stream (owned by consumer).
    PassiveStream* consumerStream;

    std::shared_ptr<MockDcpProducer> producer;

    // Non-owning ptr to producer stream (owned by producer).
    MockActiveStream* producerStream;
};

void DCPLoopbackStreamTest::readNextConsumerMsgAndSendToProducer(
        ActiveStream& producerStream, PassiveStream& consumerStream) {
    std::unique_ptr<DcpResponse> consumerMsg(consumerStream.next());

    // Pass the consumer's message to the producer.
    if (consumerMsg) {
        switch (consumerMsg->getEvent()) {
        case DcpResponse::Event::SnapshotMarker:
            producerStream.snapshotMarkerAckReceived();
            break;
        case DcpResponse::Event::SetVbucket:
            producerStream.setVBucketStateAckRecieved();
            break;
        default:
            FAIL();
        }
    }
}

/**
 * Test the behaviour of a Takeover stream between a DcpProducer and
 * DcpConsumer.
 *
 * Creates a Producer and Consumer; along with a single Active -> Passive
 * stream, then makes a streamRequest (simulating what ns_server normally does).
 * Then loops; reading messages from the producer and passing them to the
 * consumer, and reading responses from the consumer and passing to the
 * producer. Test finishes when the PassiveStream is set to Dead - at that point
 * the vBucket should be active on the destination; and dead on the source.
 */
void DCPLoopbackStreamTest::takeoverTest(
        EnableExpiryOutput enableExpiryOutput) {
    uint32_t exp_time = 0;
    if (enableExpiryOutput == EnableExpiryOutput::Yes) {
        exp_time = time(NULL) + 256;
    }

    // Add some items to the source Bucket.
    std::vector<StoredDocKey> keys;
    keys.push_back(makeStoredDocKey("key1"));
    keys.push_back(makeStoredDocKey("key2"));
    keys.push_back(makeStoredDocKey("key3"));
    for (const auto& key : keys) {
        store_item(vbid, key, "value", exp_time);
    }

    // Setup conditions for expirations
    auto expectedGetOutcome = ENGINE_SUCCESS;
    if (enableExpiryOutput == EnableExpiryOutput::Yes) {
        expectedGetOutcome = ENGINE_KEY_ENOENT;
    }
    TimeTraveller t(1080);
    // Trigger expiries on a get, or just check that the key exists
    for (const auto& key : keys) {
        EXPECT_EQ(expectedGetOutcome, getInternalHelper(key));
    }

    // Note: the order matters.
    //     First, we setup the Consumer with the given flags and we discard the
    //     StreamRequest message from the Consumer::readyQ.
    //     Then, we simulate the Producer receiving the StreamRequest just
    //     by creating the Producer with the Consumer's flags
    setupConsumer(DCP_ADD_STREAM_FLAG_TAKEOVER);
    setupProducer(enableExpiryOutput);

    // Both streams created. Check state is as expected.
    ASSERT_TRUE(producerStream->isTakeoverSend())
            << "Producer stream state should have transitioned to "
               "TakeoverSend";

    while (true) {
        auto producerMsg = getNextProducerMsg(producerStream);
        ASSERT_TRUE(producerMsg);

        // Pass the message onto the consumer.
        EXPECT_EQ(ENGINE_SUCCESS,
                  consumerStream->messageReceived(std::move(producerMsg)));

        // Get the next message from the consumer; and pass to the producer.
        readNextConsumerMsgAndSendToProducer(*producerStream, *consumerStream);

        // Check consumer stream state - drop reflecting messages when
        // stream goes dead.
        if (!consumerStream->isActive()) {
            break;
        }
    }

    auto* sourceVb = engine->getVBucket(vbid).get();
    EXPECT_EQ(vbucket_state_dead, sourceVb->getState())
            << "Expected producer vBucket to be dead once stream "
               "transitions to dead.";

    auto* destVb = replicaEngine->getVBucket(vbid).get();
    EXPECT_EQ(vbucket_state_active, destVb->getState())
            << "Expected consumer vBucket to be active once stream "
               "transitions to dead.";

    // Check final state of items
    auto num_left = 3, expired = 0;
    auto expectedOutcome = ENGINE_SUCCESS;
    if (enableExpiryOutput == EnableExpiryOutput::Yes) {
        num_left = 0, expired = 3;
        expectedOutcome = ENGINE_KEY_ENOENT;
    }
    EXPECT_EQ(num_left, sourceVb->getNumItems());
    EXPECT_EQ(num_left, destVb->getNumItems());
    EXPECT_EQ(expired, sourceVb->numExpiredItems);
    // numExpiredItems is a stat for recording how many items have been flipped
    // from active to expired on a vbucket, so does not get transferred during
    // a takeover.

    auto key1 = makeStoredDocKey("key1");
    EXPECT_EQ(expectedOutcome, getInternalHelper(key1));
}

TEST_F(DCPLoopbackStreamTest, Takeover) {
    takeoverTest(EnableExpiryOutput::No);
}

TEST_F(DCPLoopbackStreamTest, TakeoverWithExpiry) {
    takeoverTest(EnableExpiryOutput::Yes);
}
<|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "s60videowidget.h"
#ifdef USE_PRIVATE_QWIDGET_METHODS
#include <QtGui/private/qwidget_p.h>
#endif
#include <QEvent>
#include <coemain.h>    // For CCoeEnv
#include <coecntrl.h>   // For CCoeControl

QAbstractVideoWidget::QAbstractVideoWidget(QWidget *parent)
    : QWidget(parent)
{
}

QAbstractVideoWidget::~QAbstractVideoWidget()
{
}

QBlackSurface::QBlackSurface(QWidget *parent)
    : QAbstractVideoWidget(parent)
{
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION >= 0x040601 && !defined(__WINSCW__)
    qt_widget_private(this)->createExtra();
    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::Disable;
#endif
#endif
    winId();
}

QBlackSurface::~QBlackSurface()
{
}

void QBlackSurface::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    // Do nothing
}

QBlackWidget::QBlackWidget(QWidget *parent)
    : QAbstractVideoWidget(parent)
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setAttribute(Qt::WA_OpaquePaintEvent, true);
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAutoFillBackground(false);
    setPalette(QPalette(Qt::black));
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION >= 0x040601 && !defined(__WINSCW__)
    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
    qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
#endif
#endif
    winId();
}

QBlackWidget::~QBlackWidget()
{
}

void QBlackWidget::beginNativePaintEvent(const QRect& /*controlRect*/)
{
    emit beginVideoWindowNativePaint();
}

void QBlackWidget::endNativePaintEvent(const QRect& /*controlRect*/)
{
    CCoeEnv::Static()->WsSession().Flush();
    emit endVideoWindowNativePaint();
}

void QBlackWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    // Do nothing
}

S60VideoWidgetControl::S60VideoWidgetControl(QObject *parent)
    : QVideoWidgetControl(parent)
    , m_widget(0)
    , m_aspectRatioMode(Qt::KeepAspectRatio)
    , m_fullScreenEnabled(0)
{
    initializeVideoOutput();
}

void S60VideoWidgetControl::initializeVideoOutput()
{
#ifdef MMF_VIDEO_SURFACES_SUPPORTED
    m_widget.reset(new QBlackSurface());
#else
    m_widget.reset(new QBlackWidget());
    connect(m_widget.data(), SIGNAL(beginVideoWindowNativePaint()), this, SIGNAL(beginVideoWindowNativePaint()));
    connect(m_widget.data(), SIGNAL(endVideoWindowNativePaint()), this, SIGNAL(endVideoWindowNativePaint()));
#endif
    m_widget->installEventFilter(this);
}

S60VideoWidgetControl::~S60VideoWidgetControl()
{
}

QWidget *S60VideoWidgetControl::videoWidget()
{
    return m_widget.data();
}

Qt::AspectRatioMode S60VideoWidgetControl::aspectRatioMode() const
{
    return m_aspectRatioMode;
}

void S60VideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode ratio)
{
    if (m_aspectRatioMode == ratio)
        return;

    m_aspectRatioMode = ratio;
    emit widgetUpdated();
}

bool S60VideoWidgetControl::isFullScreen() const
{
    return m_fullScreenEnabled;
}

void S60VideoWidgetControl::setFullScreen(bool fullScreen)
{
    if (m_fullScreenEnabled == fullScreen)
        return;

    m_fullScreenEnabled = fullScreen;

    if (fullScreen && m_widget)
        m_widget->showFullScreen();
    else if (m_widget)
        m_widget->showNormal();

    emit fullScreenChanged(fullScreen);
}

int S60VideoWidgetControl::brightness() const
{
    return 0;
}

void S60VideoWidgetControl::setBrightness(int brightness)
{
    Q_UNUSED(brightness);
}

int S60VideoWidgetControl::contrast() const
{
     return 0;
}

void S60VideoWidgetControl::setContrast(int contrast)
{
    Q_UNUSED(contrast);
}

int S60VideoWidgetControl::hue() const
{
    return 0;
}

void S60VideoWidgetControl::setHue(int hue)
{
    Q_UNUSED(hue);
}

int S60VideoWidgetControl::saturation() const
{
    return 0;
}

void S60VideoWidgetControl::setSaturation(int saturation)
{
    Q_UNUSED(saturation);
}

bool S60VideoWidgetControl::eventFilter(QObject *object, QEvent *e)
{
    if (object == m_widget.data()) {
        if (e->type() == QEvent::ParentChange) {
            if (QWidget *parent = m_widget->parentWidget())
                parent->setProperty("_q_DummyWindowSurface", true);
            emit widgetUpdated();
        } else if (e->type() == QEvent::WinIdChange
            || e->type() == QEvent::Show) {
            emit widgetUpdated();
        } else if (e->type() == QEvent::Resize
            || e->type() == QEvent::Move) {
#ifdef MMF_VIDEO_SURFACES_SUPPORTED
           emit widgetResized();
#else
           emit widgetUpdated();
#endif //MMF_VIDEO_SURFACES_SUPPORTED

        }
    }
    return false;
}

WId S60VideoWidgetControl::videoWidgetWId()
{
    if (m_widget->internalWinId())
        return m_widget->internalWinId();

    if (m_widget->effectiveWinId())
        return m_widget->effectiveWinId();

    return NULL;
}

QSize S60VideoWidgetControl::videoWidgetSize()
{
    QSize result;
    RWindowBase *window = NULL;
    CCoeControl *control = videoWidgetWId();
    if (control)
        window = control->DrawableWindow();
    if (window) {
        const TSize size = window->Size();
        result = QSize(size.iWidth, size.iHeight);
    }
    return result;
}

void S60VideoWidgetControl::videoStateChanged(QMediaPlayer::State state)
{
    if (state == QMediaPlayer::StoppedState) {
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION <= 0x040600 && !defined(FF_QT)
        qDebug()<<"S60VideoPlayerSession::videoStateChanged() - state == QMediaPlayer::StoppedState";
        qt_widget_private(m_widget.data())->extraData()->disableBlit = false;
#endif
#endif
        m_widget->repaint();
    } else if (state == QMediaPlayer::PlayingState) {
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION <= 0x040600 && !defined(FF_QT)
        qDebug()<<"S60VideoPlayerSession::videoStateChanged() - state == QMediaPlayer::PlayingState";
        qt_widget_private(m_widget.data())->extraData()->disableBlit = true;
#endif
#endif
    }
}
<commit_msg>test2 for the widget.cpp file<commit_after>/****************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Mobility Components.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/
// ravi b
#include "s60videowidget.h"
#ifdef USE_PRIVATE_QWIDGET_METHODS
#include <QtGui/private/qwidget_p.h>
#endif
#include <QEvent>
#include <coemain.h>    // For CCoeEnv
#include <coecntrl.h>   // For CCoeControl

QAbstractVideoWidget::QAbstractVideoWidget(QWidget *parent)
    : QWidget(parent)
{
}

QAbstractVideoWidget::~QAbstractVideoWidget()
{
}

QBlackSurface::QBlackSurface(QWidget *parent)
    : QAbstractVideoWidget(parent)
{
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION >= 0x040601 && !defined(__WINSCW__)
    qt_widget_private(this)->createExtra();
    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::Disable;
#endif
#endif
    winId();
}

QBlackSurface::~QBlackSurface()
{
}

void QBlackSurface::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    // Do nothing
}

QBlackWidget::QBlackWidget(QWidget *parent)
    : QAbstractVideoWidget(parent)
{
    setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    setAttribute(Qt::WA_OpaquePaintEvent, true);
    setAttribute(Qt::WA_NoSystemBackground, true);
    setAutoFillBackground(false);
    setPalette(QPalette(Qt::black));
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION >= 0x040601 && !defined(__WINSCW__)
    qt_widget_private(this)->extraData()->nativePaintMode = QWExtra::ZeroFill;
    qt_widget_private(this)->extraData()->receiveNativePaintEvents = true;
#endif
#endif
    winId();
}

QBlackWidget::~QBlackWidget()
{
}

void QBlackWidget::beginNativePaintEvent(const QRect& /*controlRect*/)
{
    emit beginVideoWindowNativePaint();
}

void QBlackWidget::endNativePaintEvent(const QRect& /*controlRect*/)
{
    CCoeEnv::Static()->WsSession().Flush();
    emit endVideoWindowNativePaint();
}

void QBlackWidget::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    // Do nothing
}

S60VideoWidgetControl::S60VideoWidgetControl(QObject *parent)
    : QVideoWidgetControl(parent)
    , m_widget(0)
    , m_aspectRatioMode(Qt::KeepAspectRatio)
    , m_fullScreenEnabled(0)
{
    initializeVideoOutput();
}

void S60VideoWidgetControl::initializeVideoOutput()
{
#ifdef MMF_VIDEO_SURFACES_SUPPORTED
    m_widget.reset(new QBlackSurface());
#else
    m_widget.reset(new QBlackWidget());
    connect(m_widget.data(), SIGNAL(beginVideoWindowNativePaint()), this, SIGNAL(beginVideoWindowNativePaint()));
    connect(m_widget.data(), SIGNAL(endVideoWindowNativePaint()), this, SIGNAL(endVideoWindowNativePaint()));
#endif
    m_widget->installEventFilter(this);
}

S60VideoWidgetControl::~S60VideoWidgetControl()
{
}

QWidget *S60VideoWidgetControl::videoWidget()
{
    return m_widget.data();
}

Qt::AspectRatioMode S60VideoWidgetControl::aspectRatioMode() const
{
    return m_aspectRatioMode;
}

void S60VideoWidgetControl::setAspectRatioMode(Qt::AspectRatioMode ratio)
{
    if (m_aspectRatioMode == ratio)
        return;

    m_aspectRatioMode = ratio;
    emit widgetUpdated();
}

bool S60VideoWidgetControl::isFullScreen() const
{
    return m_fullScreenEnabled;
}

void S60VideoWidgetControl::setFullScreen(bool fullScreen)
{
    if (m_fullScreenEnabled == fullScreen)
        return;

    m_fullScreenEnabled = fullScreen;

    if (fullScreen && m_widget)
        m_widget->showFullScreen();
    else if (m_widget)
        m_widget->showNormal();

    emit fullScreenChanged(fullScreen);
}

int S60VideoWidgetControl::brightness() const
{
    return 0;
}

void S60VideoWidgetControl::setBrightness(int brightness)
{
    Q_UNUSED(brightness);
}

int S60VideoWidgetControl::contrast() const
{
     return 0;
}

void S60VideoWidgetControl::setContrast(int contrast)
{
    Q_UNUSED(contrast);
}

int S60VideoWidgetControl::hue() const
{
    return 0;
}

void S60VideoWidgetControl::setHue(int hue)
{
    Q_UNUSED(hue);
}

int S60VideoWidgetControl::saturation() const
{
    return 0;
}

void S60VideoWidgetControl::setSaturation(int saturation)
{
    Q_UNUSED(saturation);
}

bool S60VideoWidgetControl::eventFilter(QObject *object, QEvent *e)
{
    if (object == m_widget.data()) {
        if (e->type() == QEvent::ParentChange) {
            if (QWidget *parent = m_widget->parentWidget())
                parent->setProperty("_q_DummyWindowSurface", true);
            emit widgetUpdated();
        } else if (e->type() == QEvent::WinIdChange
            || e->type() == QEvent::Show) {
            emit widgetUpdated();
        } else if (e->type() == QEvent::Resize
            || e->type() == QEvent::Move) {
#ifdef MMF_VIDEO_SURFACES_SUPPORTED
           emit widgetResized();
#else
           emit widgetUpdated();
#endif //MMF_VIDEO_SURFACES_SUPPORTED

        }
    }
    return false;
}

WId S60VideoWidgetControl::videoWidgetWId()
{
    if (m_widget->internalWinId())
        return m_widget->internalWinId();

    if (m_widget->effectiveWinId())
        return m_widget->effectiveWinId();

    return NULL;
}

QSize S60VideoWidgetControl::videoWidgetSize()
{
    QSize result;
    RWindowBase *window = NULL;
    CCoeControl *control = videoWidgetWId();
    if (control)
        window = control->DrawableWindow();
    if (window) {
        const TSize size = window->Size();
        result = QSize(size.iWidth, size.iHeight);
    }
    return result;
}

void S60VideoWidgetControl::videoStateChanged(QMediaPlayer::State state)
{
    if (state == QMediaPlayer::StoppedState) {
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION <= 0x040600 && !defined(FF_QT)
        qDebug()<<"S60VideoPlayerSession::videoStateChanged() - state == QMediaPlayer::StoppedState";
        qt_widget_private(m_widget.data())->extraData()->disableBlit = false;
#endif
#endif
        m_widget->repaint();
    } else if (state == QMediaPlayer::PlayingState) {
#ifdef USE_PRIVATE_QWIDGET_METHODS
#if QT_VERSION <= 0x040600 && !defined(FF_QT)
        qDebug()<<"S60VideoPlayerSession::videoStateChanged() - state == QMediaPlayer::PlayingState";
        qt_widget_private(m_widget.data())->extraData()->disableBlit = true;
#endif
#endif
    }
}
<|endoftext|>


<commit_before>/*==========================================================================

  Program:
  Module:    otherTimerLog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  ==========================================================================*/

// .NAME
// .SECTION Description
// this program tests the TimerLog

#include "vtkTimerLog.h"
#include "vtkDebugLeaks.h"

void Test(ostream& strm)
{
  // actual test
  float a = 1.0, b = 2.0;
  int i, j;
  strm << "Test vtkTimerLog Start" << endl;
  vtkTimerLog *timer1 = vtkTimerLog::New();

  timer1->SetMaxEntries (5);
  timer1->StartTimer();
  for (j = 0; j < 10; j++)
    {
    timer1->FormatAndMarkEvent("%s%d", "start", j);
    for (i = 0; i < 10000000; i++)
      {
      a *= b;
      }
#ifndef WIN32
    sleep (1);
#else
    Sleep(1000);
#endif
    timer1->FormatAndMarkEvent("%s%d", "end", j);
    }
  timer1->StopTimer();
  strm << "GetElapsedTime: " << timer1->GetElapsedTime() << endl;
  strm << "GetCPUTime: " << timer1->GetCPUTime() << endl;
  timer1->DumpLog( "timing" );
  timer1->ResetLog ();
  unlink("timing");
  timer1->Delete();
  strm << "Test vtkTimerLog End" << endl;
}

int main(int argc, char* argv[])
{
  vtkDebugLeaks::PromptUserOff();

  Test(cout);

  return 0;
}
<commit_msg>ERR: cygwin needs stdio.h.<commit_after>/*==========================================================================

  Program:
  Module:    otherTimerLog.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  ==========================================================================*/

// .NAME
// .SECTION Description
// this program tests the TimerLog

#include <stdio.h>
#include "vtkTimerLog.h"
#include "vtkDebugLeaks.h"

void Test(ostream& strm)
{
  // actual test
  float a = 1.0, b = 2.0;
  int i, j;
  strm << "Test vtkTimerLog Start" << endl;
  vtkTimerLog *timer1 = vtkTimerLog::New();

  timer1->SetMaxEntries (5);
  timer1->StartTimer();
  for (j = 0; j < 10; j++)
    {
    timer1->FormatAndMarkEvent("%s%d", "start", j);
    for (i = 0; i < 10000000; i++)
      {
      a *= b;
      }
#ifndef WIN32
    sleep (1);
#else
    Sleep(1000);
#endif
    timer1->FormatAndMarkEvent("%s%d", "end", j);
    }
  timer1->StopTimer();
  strm << "GetElapsedTime: " << timer1->GetElapsedTime() << endl;
  strm << "GetCPUTime: " << timer1->GetCPUTime() << endl;
  timer1->DumpLog( "timing" );
  timer1->ResetLog ();
  unlink("timing");
  timer1->Delete();
  strm << "Test vtkTimerLog End" << endl;
}

int main(int argc, char* argv[])
{
  vtkDebugLeaks::PromptUserOff();

  Test(cout);

  return 0;
}
<|endoftext|>


<commit_before>// Arguments: Double, Double
#include <stan/prob/distributions/univariate/continuous/inv_gamma.hpp>

using std::vector;
using std::numeric_limits;
using stan::agrad::var;

class AgradCdfInvGamma : public AgradCdfTest {
public:
  void valid_values(vector<vector<double> >& parameters,
		    vector<double>& cdf) {
    vector<double> param(3);

    param[0] = 3.0;           // y
    param[1] = 0.5;           // alpha (Shape)
    param[2] = 3.3;           // beta (Scale)
    parameters.push_back(param);
    cdf.push_back(0.138011);  // expected CDF

  }

  void invalid_values(vector<size_t>& index,
		      vector<double>& value) {

    // y
    index.push_back(0U);
    value.push_back(-1.0);

    // alpha
    index.push_back(1U);
    value.push_back(-1.0);

    index.push_back(1U);
    value.push_back(0.0);

    index.push_back(1U);
    value.push_back(numeric_limits<double>::infinity());

    // beta
    index.push_back(2U);
    value.push_back(-1.0);

    index.push_back(2U);
    value.push_back(0.0);

    index.push_back(2U);
    value.push_back(numeric_limits<double>::infinity());

  }

  bool has_lower_bound() {
    return true;
  }

  double lower_bound() {
    return 0.0;
  }

  bool has_upper_bound() {
    return false;
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf(const T_y& y, const T_shape& alpha, const T_scale& beta,
      const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
    return stan::prob::inv_gamma_cdf(y, alpha, beta);
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9,
	    typename Policy>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf(const T_y& y, const T_shape& alpha, const T_scale& beta,
      const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
    return stan::prob::inv_gamma_cdf(y, alpha, beta, Policy());
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf_function(const T_y& y, const T_shape& alpha, const T_scale& beta,
	       const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
      return stan::prob::inv_gamma_cdf(y, alpha, beta);
  }

};
<commit_msg>Added missing Double, vectorized tests.<commit_after>// Arguments: Doubles, Doubles, Doubles
#include <stan/prob/distributions/univariate/continuous/inv_gamma.hpp>

using std::vector;
using std::numeric_limits;
using stan::agrad::var;

class AgradCdfInvGamma : public AgradCdfTest {
public:
  void valid_values(vector<vector<double> >& parameters,
		    vector<double>& cdf) {
    vector<double> param(3);

    param[0] = 3.0;           // y
    param[1] = 0.5;           // alpha (Shape)
    param[2] = 3.3;           // beta (Scale)
    parameters.push_back(param);
    cdf.push_back(0.138010737);  // expected CDF

  }

  void invalid_values(vector<size_t>& index,
		      vector<double>& value) {

    // y
    index.push_back(0U);
    value.push_back(-1.0);

    // alpha
    index.push_back(1U);
    value.push_back(-1.0);

    index.push_back(1U);
    value.push_back(0.0);

    index.push_back(1U);
    value.push_back(numeric_limits<double>::infinity());

    // beta
    index.push_back(2U);
    value.push_back(-1.0);

    index.push_back(2U);
    value.push_back(0.0);

    index.push_back(2U);
    value.push_back(numeric_limits<double>::infinity());

  }

  bool has_lower_bound() {
    return true;
  }

  double lower_bound() {
    return 0.0;
  }

  bool has_upper_bound() {
    return false;
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf(const T_y& y, const T_shape& alpha, const T_scale& beta,
      const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
    return stan::prob::inv_gamma_cdf(y, alpha, beta);
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9,
	    typename Policy>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf(const T_y& y, const T_shape& alpha, const T_scale& beta,
      const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
    return stan::prob::inv_gamma_cdf(y, alpha, beta, Policy());
  }

  template <typename T_y, typename T_shape, typename T_scale,
	    typename T3, typename T4, typename T5,
	    typename T6, typename T7, typename T8,
	    typename T9>
  typename stan::return_type<T_y, T_shape, T_scale>::type
  cdf_function(const T_y& y, const T_shape& alpha, const T_scale& beta,
	       const T3&, const T4&, const T5&, const T6&, const T7&, const T8&, const T9&) {
      return stan::prob::inv_gamma_cdf(y, alpha, beta);
  }

};
<|endoftext|>


<commit_before>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <cassert>

#if defined(XALAN_OLD_STREAM_HEADERS)
#include <iostream.h>
#else
#include <iostream>
#endif

#include <util/PlatformUtils.hpp>
#include <util/Mutexes.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanFileOutputStream.hpp>
#include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>

#include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
#include <XalanSourceTree/XalanSourceTreeParserLiaison.hpp>

#include <XPath/XObjectFactoryDefault.hpp>
#include <XPath/XPathFactoryDefault.hpp>

#include <XSLT/StylesheetConstructionContextDefault.hpp>
#include <XSLT/StylesheetExecutionContextDefault.hpp>
#include <XSLT/StylesheetRoot.hpp>
#include <XSLT/XSLTEngineImpl.hpp>
#include <XSLT/XSLTInit.hpp>
#include <XSLT/XSLTInputSource.hpp>
#include <XSLT/XSLTProcessorEnvSupportDefault.hpp>
#include <XSLT/XSLTResultTarget.hpp>

#if defined(WIN32)
//This is here for the threads.
#include <process.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(XALAN_POSIX2_AVAILABLE)
#include <pthread.h>
#include <unistd.h>
#else
#error Unsupported platform!
#endif

#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::vector;
#endif

// This is here for memory leak testing.
#if defined(_DEBUG)
#include <crtdbg.h>
#endif

// Used to hold compiled stylesheet
StylesheetRoot* glbStylesheetRoot;

class SynchronizedCounter
{
public:

	SynchronizedCounter();

	~SynchronizedCounter();

	void
	increment();

	void
	decrement();

	unsigned long
	getCounter() const;

private:

	mutable XMLMutex	m_mutex;

	unsigned long		m_counter;
};

SynchronizedCounter::SynchronizedCounter() :
	m_mutex(),
	m_counter(0)
{
}

SynchronizedCounter::~SynchronizedCounter()
{
}

void
SynchronizedCounter::increment()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter < ULONG_MAX)
	{
		++m_counter;
	}
}

void
SynchronizedCounter::decrement()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter > 0)
	{
		--m_counter;
	}
}

unsigned long
SynchronizedCounter::getCounter() const
{
	return m_counter;
}

struct
ThreadInfo
{
	ThreadInfo(
			unsigned int			theThreadNumber,
			SynchronizedCounter*	theCounter) :
		m_threadNumber(theThreadNumber),
		m_counter(theCounter)
	{
	}

	unsigned int			m_threadNumber;

	SynchronizedCounter*	m_counter;
};

#if defined(WIN32)

extern "C" void theThreadRoutine(void* param);

void
#elif defined(XALAN_POSIX2_AVAILABLE)

extern "C" void* theThreadRoutine(void* param);

void*
#else
#error Unsupported platform!
#endif
theThreadRoutine(void*		param)
{
// This routine uses compiled stylesheet (glbStylesheetRoot), which is set using the
// theProcessor.setStylesheetRoot method. The transform is done using the theProcessor's
// process() method.

	const ThreadInfo*	theInfo = reinterpret_cast<const ThreadInfo*>(param);

	assert(theInfo != 0);

	theInfo->m_counter->increment();

	try
	{
		// Create the support objects that are necessary for running the processor...
		XalanSourceTreeDOMSupport		theDOMSupport;
		XalanSourceTreeParserLiaison	theParserLiaison(theDOMSupport);

		theDOMSupport.setParserLiaison(&theParserLiaison);
		// The default is that documents are not thread-safe.  Set this to
		// true so they are.
		//theParserLiaison.setThreadSafe(true);

		XSLTProcessorEnvSupportDefault	theXSLTProcessorEnvSupport;
		XObjectFactoryDefault			theXObjectFactory;
		XPathFactoryDefault				theXPathFactory;

		// Create a processor...and output start message.
		XSLTEngineImpl	theProcessor(
						theParserLiaison,
						theXSLTProcessorEnvSupport,
						theDOMSupport,
						theXObjectFactory,
						theXPathFactory);

		// Connect the processor to the support object...
		theXSLTProcessorEnvSupport.setProcessor(&theProcessor);

		// The execution context uses the same factory support objects as
		// the processor, since those objects have the same lifetime as
		// other objects created as a result of the execution.
		StylesheetExecutionContextDefault	ssExecutionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theDOMSupport,
							theXObjectFactory);

		// Our input files.  The assumption is that the executable will be run
		// from same directory as the input files.

		// Generate the input and output file names.
		const XalanDOMString	theXMLfile("birds.xml");

		const XalanDOMString	theOutputFile(
				XalanDOMString("birds") +
				UnsignedLongToDOMString(theInfo->m_threadNumber) +
				XalanDOMString(".out"));

		//Generate the XML input and output objects.
		XSLTInputSource		theInputSource(c_wstr(theXMLfile));
		XSLTResultTarget	theResultTarget(theOutputFile);

		// Set the stylesheet to be the compiled stylesheet. Then do the transform.
		// Report both the start of the transform and end of the thread.
		theProcessor.setStylesheetRoot(glbStylesheetRoot);
		theProcessor.process(theInputSource,theResultTarget,ssExecutionContext);
	}
	catch(...)
	{
	}

	// Decrement the counter because we're done...
	theInfo->m_counter->decrement();

#if defined(XALAN_POSIX2_AVAILABLE)
	return 0;
#endif
}

inline void
doSleep(unsigned int	theMilliseconds)
{
#if defined(WIN32)
	Sleep(theMilliseconds);
#elif defined(XALAN_POSIX2_AVAILABLE)
	usleep(theMilliseconds * 10);
#else
#error Unsupported platform!
#endif
}

void
doThreads(long	theThreadCount)
{
	cout << endl << "Starting " << theThreadCount << " threads." << endl;

	typedef vector<ThreadInfo>		ThreadInfoVectorType;

	ThreadInfoVectorType	theThreadInfo;

	theThreadInfo.reserve(theThreadCount);

	try
	{
		cout << endl << "Clock before starting threads: " << clock() << endl;

		SynchronizedCounter		theCounter;

		for (long i = 0; i < theThreadCount; i++)
		{
			theThreadInfo.push_back(ThreadInfoVectorType::value_type(i, &theCounter));

#if defined(WIN32)

			const unsigned long		theThreadID =
					_beginthread(theThreadRoutine, 4096, reinterpret_cast<LPVOID>(&theThreadInfo.back()));

			if (theThreadID == unsigned(-1))
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}

#elif defined(XALAN_POSIX2_AVAILABLE)

			pthread_t	theThread;

			const int	theResult = pthread_create(&theThread, 0, theThreadRoutine, (void*)&theThreadInfo.back());

			if (theResult != 0)
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}
			else
			{
				pthread_detach(theThread);
			}
#else
#error Unsupported platform!
#endif
		}

		clock_t		theClock = 0;

		if (theThreadInfo.size() == 0)
		{
			cerr << endl << "No threads were created!" << endl;
		}
		else
		{
			unsigned int	theCheckCount = 0;

			do
			{
				doSleep(2000);

				// Check a couple of times, just in case, since
				// getCounter() is not synchronized...
				if (theCounter.getCounter() == 0)
				{
					if (theCheckCount == 0)
					{
						theClock = clock();
					}

					++theCheckCount;
				}
			}
			while(theCheckCount < 2);
		}

		cout << endl << "Clock after threads: " << theClock << endl;
	}
	catch(...)
	{
		cerr << "Exception caught!!!"
			 << endl
			<< endl;
	}
}

int
main(
			int				argc,
			const char*		argv[])
{
#if !defined(NDEBUG) && defined(_MSC_VER)
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

	_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif

	if (argc > 2)
	{
		cerr << "Usage: ThreadTest"
			 << endl
			 << endl;
	}
	else
	{
		int	threadCount = 60;

		if (argc == 2)
		{
			threadCount = atoi(argv[1]);
		}

		try
		{
		  // Call the static initializers...
		  XMLPlatformUtils::Initialize();
          {
			XSLTInit	theInit;

			// Create the necessary stuff of compile the stylesheet.
			XercesDOMSupport				ssDOMSupport;
			XercesParserLiaison				ssParserLiaison(ssDOMSupport);
			XSLTProcessorEnvSupportDefault	ssXSLTProcessorEnvSupport;
			XObjectFactoryDefault			ssXObjectFactory;
			XPathFactoryDefault				ssXPathFactory;

			// Create a processor to compile the stylesheet...
			XSLTEngineImpl	ssProcessor(
					ssParserLiaison,
					ssXSLTProcessorEnvSupport,
					ssDOMSupport,
					ssXObjectFactory,
					ssXPathFactory);

			// Create separate factory support objects so the stylesheet's
			// factory-created XObject and XPath instances are independent
			// from processor's.
			XPathFactoryDefault		ssStylesheetXPathFactory;

			// Create a stylesheet construction context, using the
			// stylesheet's factory support objects.
			StylesheetConstructionContextDefault	ssConstructionContext(
													ssProcessor,
													ssXSLTProcessorEnvSupport,
													ssStylesheetXPathFactory);

			const XalanDOMString  theXSLFileName("birds.xsl");
			const XalanDOMString  theXMLFileName("birds.xml");

			// Our stylesheet input source...
			XSLTInputSource		ssStylesheetSourceXSL(c_wstr(theXSLFileName));
			XSLTInputSource		ssStylesheetSourceXML(c_wstr(theXMLFileName));

			// Ask the processor to create a StylesheetRoot for the specified
			// input XSL.  This is the compiled stylesheet.  We don't have to
			// delete it, since it is owned by the StylesheetConstructionContext
			// instance.

			glbStylesheetRoot = ssProcessor.processStylesheet(ssStylesheetSourceXSL,
													   ssConstructionContext);
			assert(glbStylesheetRoot != 0);

			doThreads(threadCount);
		  }

		XMLPlatformUtils::Terminate();

		}

		catch(...)
		{
			cerr << "Exception caught!!!"
				 << endl
				 << endl;
		}

	}

	return 0;
}
<commit_msg>Added error message in catch(...).<commit_after>// Base header file.  Must be first.
#include <Include/PlatformDefinitions.hpp>

#include <cassert>

#if defined(XALAN_OLD_STREAM_HEADERS)
#include <iostream.h>
#else
#include <iostream>
#endif

#include <util/PlatformUtils.hpp>
#include <util/Mutexes.hpp>

#include <PlatformSupport/DOMStringHelper.hpp>
#include <PlatformSupport/XalanFileOutputStream.hpp>
#include <PlatformSupport/XalanOutputStreamPrintWriter.hpp>

#include <XalanSourceTree/XalanSourceTreeDOMSupport.hpp>
#include <XalanSourceTree/XalanSourceTreeParserLiaison.hpp>

#include <XPath/XObjectFactoryDefault.hpp>
#include <XPath/XPathFactoryDefault.hpp>

#include <XSLT/StylesheetConstructionContextDefault.hpp>
#include <XSLT/StylesheetExecutionContextDefault.hpp>
#include <XSLT/StylesheetRoot.hpp>
#include <XSLT/XSLTEngineImpl.hpp>
#include <XSLT/XSLTInit.hpp>
#include <XSLT/XSLTInputSource.hpp>
#include <XSLT/XSLTProcessorEnvSupportDefault.hpp>
#include <XSLT/XSLTResultTarget.hpp>

#if defined(WIN32)
//This is here for the threads.
#include <process.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#elif defined(XALAN_POSIX2_AVAILABLE)
#include <pthread.h>
#include <unistd.h>
#else
#error Unsupported platform!
#endif

#if !defined(XALAN_NO_NAMESPACES)
	using std::cerr;
	using std::cout;
	using std::endl;
	using std::vector;
#endif

// This is here for memory leak testing.
#if defined(_DEBUG)
#include <crtdbg.h>
#endif

// Used to hold compiled stylesheet
StylesheetRoot* glbStylesheetRoot;

class SynchronizedCounter
{
public:

	SynchronizedCounter();

	~SynchronizedCounter();

	void
	increment();

	void
	decrement();

	unsigned long
	getCounter() const;

private:

	mutable XMLMutex	m_mutex;

	unsigned long		m_counter;
};

SynchronizedCounter::SynchronizedCounter() :
	m_mutex(),
	m_counter(0)
{
}

SynchronizedCounter::~SynchronizedCounter()
{
}

void
SynchronizedCounter::increment()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter < ULONG_MAX)
	{
		++m_counter;
	}
}

void
SynchronizedCounter::decrement()
{
	XMLMutexLock	theLock(&m_mutex);

	if (m_counter > 0)
	{
		--m_counter;
	}
}

unsigned long
SynchronizedCounter::getCounter() const
{
	return m_counter;
}

struct
ThreadInfo
{
	ThreadInfo(
			unsigned int			theThreadNumber,
			SynchronizedCounter*	theCounter) :
		m_threadNumber(theThreadNumber),
		m_counter(theCounter)
	{
	}

	unsigned int			m_threadNumber;

	SynchronizedCounter*	m_counter;
};

#if defined(WIN32)

extern "C" void theThreadRoutine(void* param);

void
#elif defined(XALAN_POSIX2_AVAILABLE)

extern "C" void* theThreadRoutine(void* param);

void*
#else
#error Unsupported platform!
#endif
theThreadRoutine(void*		param)
{
// This routine uses compiled stylesheet (glbStylesheetRoot), which is set using the
// theProcessor.setStylesheetRoot method. The transform is done using the theProcessor's
// process() method.

	const ThreadInfo*	theInfo = reinterpret_cast<const ThreadInfo*>(param);

	assert(theInfo != 0);

	theInfo->m_counter->increment();

	try
	{
		// Create the support objects that are necessary for running the processor...
		XalanSourceTreeDOMSupport		theDOMSupport;
		XalanSourceTreeParserLiaison	theParserLiaison(theDOMSupport);

		theDOMSupport.setParserLiaison(&theParserLiaison);
		// The default is that documents are not thread-safe.  Set this to
		// true so they are.
		//theParserLiaison.setThreadSafe(true);

		XSLTProcessorEnvSupportDefault	theXSLTProcessorEnvSupport;
		XObjectFactoryDefault			theXObjectFactory;
		XPathFactoryDefault				theXPathFactory;

		// Create a processor...and output start message.
		XSLTEngineImpl	theProcessor(
						theParserLiaison,
						theXSLTProcessorEnvSupport,
						theDOMSupport,
						theXObjectFactory,
						theXPathFactory);

		// Connect the processor to the support object...
		theXSLTProcessorEnvSupport.setProcessor(&theProcessor);

		// The execution context uses the same factory support objects as
		// the processor, since those objects have the same lifetime as
		// other objects created as a result of the execution.
		StylesheetExecutionContextDefault	ssExecutionContext(
							theProcessor,
							theXSLTProcessorEnvSupport,
							theDOMSupport,
							theXObjectFactory);

		// Our input files.  The assumption is that the executable will be run
		// from same directory as the input files.

		// Generate the input and output file names.
		const XalanDOMString	theXMLfile("birds.xml");

		const XalanDOMString	theOutputFile(
				XalanDOMString("birds") +
				UnsignedLongToDOMString(theInfo->m_threadNumber) +
				XalanDOMString(".out"));

		//Generate the XML input and output objects.
		XSLTInputSource		theInputSource(c_wstr(theXMLfile));
		XSLTResultTarget	theResultTarget(theOutputFile);

		// Set the stylesheet to be the compiled stylesheet. Then do the transform.
		// Report both the start of the transform and end of the thread.
		theProcessor.setStylesheetRoot(glbStylesheetRoot);
		theProcessor.process(theInputSource,theResultTarget,ssExecutionContext);
	}
	catch(...)
	{
		cerr << "Exception caught in thread " << theInfo->m_threadNumber;
	}

	// Decrement the counter because we're done...
	theInfo->m_counter->decrement();

#if defined(XALAN_POSIX2_AVAILABLE)
	return 0;
#endif
}

inline void
doSleep(unsigned int	theMilliseconds)
{
#if defined(WIN32)
	Sleep(theMilliseconds);
#elif defined(XALAN_POSIX2_AVAILABLE)
	usleep(theMilliseconds * 10);
#else
#error Unsupported platform!
#endif
}

void
doThreads(long	theThreadCount)
{
	cout << endl << "Starting " << theThreadCount << " threads." << endl;

	typedef vector<ThreadInfo>		ThreadInfoVectorType;

	ThreadInfoVectorType	theThreadInfo;

	theThreadInfo.reserve(theThreadCount);

	try
	{
		cout << endl << "Clock before starting threads: " << clock() << endl;

		SynchronizedCounter		theCounter;

		for (long i = 0; i < theThreadCount; i++)
		{
			theThreadInfo.push_back(ThreadInfoVectorType::value_type(i, &theCounter));

#if defined(WIN32)

			const unsigned long		theThreadID =
					_beginthread(theThreadRoutine, 4096, reinterpret_cast<LPVOID>(&theThreadInfo.back()));

			if (theThreadID == unsigned(-1))
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}

#elif defined(XALAN_POSIX2_AVAILABLE)

			pthread_t	theThread;

			const int	theResult = pthread_create(&theThread, 0, theThreadRoutine, (void*)&theThreadInfo.back());

			if (theResult != 0)
			{
				cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
			}
			else
			{
				pthread_detach(theThread);
			}
#else
#error Unsupported platform!
#endif
		}

		clock_t		theClock = 0;

		if (theThreadInfo.size() == 0)
		{
			cerr << endl << "No threads were created!" << endl;
		}
		else
		{
			unsigned int	theCheckCount = 0;

			do
			{
				doSleep(2000);

				// Check a couple of times, just in case, since
				// getCounter() is not synchronized...
				if (theCounter.getCounter() == 0)
				{
					if (theCheckCount == 0)
					{
						theClock = clock();
					}

					++theCheckCount;
				}
			}
			while(theCheckCount < 2);
		}

		cout << endl << "Clock after threads: " << theClock << endl;
	}
	catch(...)
	{
		cerr << "Exception caught!!!"
			 << endl
			<< endl;
	}
}

int
main(
			int				argc,
			const char*		argv[])
{
#if !defined(NDEBUG) && defined(_MSC_VER)
	_CrtSetDbgFlag(_CrtSetDbgFlag(_CRTDBG_REPORT_FLAG) | _CRTDBG_LEAK_CHECK_DF);

	_CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE);
	_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif

	if (argc > 2)
	{
		cerr << "Usage: ThreadTest"
			 << endl
			 << endl;
	}
	else
	{
		int	threadCount = 60;

		if (argc == 2)
		{
			threadCount = atoi(argv[1]);
		}

		try
		{
		  // Call the static initializers...
		  XMLPlatformUtils::Initialize();
          {
			XSLTInit	theInit;

			// Create the necessary stuff of compile the stylesheet.
			XercesDOMSupport				ssDOMSupport;
			XercesParserLiaison				ssParserLiaison(ssDOMSupport);
			XSLTProcessorEnvSupportDefault	ssXSLTProcessorEnvSupport;
			XObjectFactoryDefault			ssXObjectFactory;
			XPathFactoryDefault				ssXPathFactory;

			// Create a processor to compile the stylesheet...
			XSLTEngineImpl	ssProcessor(
					ssParserLiaison,
					ssXSLTProcessorEnvSupport,
					ssDOMSupport,
					ssXObjectFactory,
					ssXPathFactory);

			// Create separate factory support objects so the stylesheet's
			// factory-created XObject and XPath instances are independent
			// from processor's.
			XPathFactoryDefault		ssStylesheetXPathFactory;

			// Create a stylesheet construction context, using the
			// stylesheet's factory support objects.
			StylesheetConstructionContextDefault	ssConstructionContext(
													ssProcessor,
													ssXSLTProcessorEnvSupport,
													ssStylesheetXPathFactory);

			const XalanDOMString  theXSLFileName("birds.xsl");
			const XalanDOMString  theXMLFileName("birds.xml");

			// Our stylesheet input source...
			XSLTInputSource		ssStylesheetSourceXSL(c_wstr(theXSLFileName));
			XSLTInputSource		ssStylesheetSourceXML(c_wstr(theXMLFileName));

			// Ask the processor to create a StylesheetRoot for the specified
			// input XSL.  This is the compiled stylesheet.  We don't have to
			// delete it, since it is owned by the StylesheetConstructionContext
			// instance.

			glbStylesheetRoot = ssProcessor.processStylesheet(ssStylesheetSourceXSL,
													   ssConstructionContext);
			assert(glbStylesheetRoot != 0);

			doThreads(threadCount);
		  }

		XMLPlatformUtils::Terminate();

		}

		catch(...)
		{
			cerr << "Exception caught!!!"
				 << endl
				 << endl;
		}

	}

	return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <queue>
#include <sstream>
#include "tree.h"

using namespace std;

/**
 * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer,
 * or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
 *
 * Design an algorithm to serialize and deserialize a binary tree.
 * There is no restriction on how your serialization/deserialization algorithm should work.
 * You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
 *
 * For example, you may serialize the following tree
 *
 *       1
 *      / \
 *     2   3
 *        / \
 *       4   5
 * as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree.
 * You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
 * Note: Do not use class member/global/static variables to store states.
 * Your serialize and deserialize algorithms should be stateless.
 * */

//
// Created by zhangxin on 16/1/31.
//

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string result = "[";
        queue<TreeNode*> q;
        TreeNode* node = NULL;
        if(root == NULL)
            return result;

        q.push(root);
        result += to_string(root->val);
        while(!q.empty()) {
            node = q.front();
            q.pop();

            result += ",";
            result += root->left ? to_string(root->left->val) : "null";
            result += ",";
            result += root->right ? to_string(root->right->val) : "null";

            if(root->left)
                q.push(root->left);

            if(root->right)
                q.push(root->right);
        }

        result += "]";
        return result;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        stringstream ss(data.substr(1, data.length() - 1));
        string item;
        vector<string> elements;
        queue<TreeNode*> q;
        while(getline(ss, item, ','))
            elements.push_back(item);

        int len = elements.size();
        if(len == 0)
            return NULL;

        TreeNode* root = new TreeNode(atoi(elements[0].c_str()));
        q.push(root);
        for(int i = 0; i < len / 2; i++) {
            TreeNode* left = elements[2 * i + 1] == "null" ? NULL : new TreeNode(atoi(elements[2 * i + 1].c_str()));
            TreeNode* right = elements[2 * i + 2] == "null" ? NULL : new TreeNode(atoi(elements[2 * i + 2].c_str()));
            if(left)
                q.push(left);
            if(right)
                q.push(right);

            TreeNode* node = q.front();
            q.pop();
            node->left = left;
            node->right = right;
        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));<commit_msg>add one new file<commit_after>#include <iostream>
#include <queue>
#include <sstream>
#include "tree.h"

using namespace std;

/**
 * Serialization is the process of converting a data structure or object into a sequence of bits so that it can be stored in a file or memory buffer,
 * or transmitted across a network connection link to be reconstructed later in the same or another computer environment.
 *
 * Design an algorithm to serialize and deserialize a binary tree.
 * There is no restriction on how your serialization/deserialization algorithm should work.
 * You just need to ensure that a binary tree can be serialized to a string and this string can be deserialized to the original tree structure.
 *
 * For example, you may serialize the following tree
 *
 *       1
 *      / \
 *     2   3
 *        / \
 *       4   5
 * as "[1,2,3,null,null,4,5]", just the same as how LeetCode OJ serializes a binary tree.
 * You do not necessarily need to follow this format, so please be creative and come up with different approaches yourself.
 * Note: Do not use class member/global/static variables to store states.
 * Your serialize and deserialize algorithms should be stateless.
 * */

//
// Created by zhangxin on 16/1/31.
//

class Codec {
public:

    // Encodes a tree to a single string.
    string serialize(TreeNode* root) {
        string result = "[";
        queue<TreeNode*> q;
        TreeNode* node = NULL;
        if(root == NULL)
            return result;

        q.push(root);
        result += to_string(root->val);
        while(!q.empty()) {
            node = q.front();
            q.pop();

            result += ",";
            result += root->left ? to_string(root->left->val) : "null";
            result += ",";
            result += root->right ? to_string(root->right->val) : "null";

            if(root->left)
                q.push(root->left);

            if(root->right)
                q.push(root->right);
        }

        result += "]";
        return result;
    }

    // Decodes your encoded data to tree.
    TreeNode* deserialize(string data) {
        stringstream ss(data.substr(1, data.length() - 1));
        string item;
        vector<string> elements;
        queue<TreeNode*> q;
        while(getline(ss, item, ','))
            elements.push_back(item);

        int len = elements.size();
        if(len == 0)
            return NULL;

        TreeNode* root = new TreeNode(atoi(elements[0].c_str()));
        q.push(root);
        for(int i = 0; i < len / 2; i++) {
            TreeNode* left = elements[2 * i + 1] == "null" ? NULL : new TreeNode(atoi(elements[2 * i + 1].c_str()));
            TreeNode* right = elements[2 * i + 2] == "null" ? NULL : new TreeNode(atoi(elements[2 * i + 2].c_str()));
            if(left)
                q.push(left);
            if(right)
                q.push(right);

            TreeNode* node = q.front();
            q.pop();
            node->left = left;
            node->right = right;
        }
        return root;
    }
};

// Your Codec object will be instantiated and called as such:
// Codec codec;
// codec.deserialize(codec.serialize(root));<|endoftext|>


<commit_before>/*
 * Clipper
 * Extension Class for Jamoma DSP
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTDSP.h"

#define thisTTClass				Clipper
#define thisTTClassName			"clipper"
#define thisTTClassDescription	"Limits the amplitude of signals."
#define thisTTClassTags			"audio, processor"

/**	Hard-clip signals to a low and high bound. */

class Clipper : TTAudioObjectBase {
	TTCLASS_SETUP(Clipper)

	TTFloat64	mLowBound;		///< Attribute: low bound for clipping
	TTFloat64	mHighBound;		///< Attribute: high bound for clipping

	TTErr calculateValue(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
	{
		y = x;
		TTLimit(y, mLowBound, mHighBound);
		return kTTErrNone;
	}

	/** Audio Processing Method */
	TTErr processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
	{
		TT_WRAP_CALCULATE_METHOD(calculateValue);
	}
};

TT_AUDIO_CONSTRUCTOR_EXPORT(Clipper)
{
	addAttribute(		LowBound,	kTypeFloat64);
	addMessageProperty(	LowBound,	description,	TT("Sets the minimum amplitude."));

	addAttribute(HighBound,	kTypeFloat64);
	addMessageProperty(LowBound,	description,	TT("Sets the maximum amplitude."));

	setAttributeValue(TT("lowBound"), -1.0);
	setAttributeValue(TT("highBound"), 1.0);
	setProcessMethod(processAudio);
}

Clipper::~Clipper()
{;}
<commit_msg>TTClipper extension: fix for description property on the HighBound attribute actually setting the description for the LowBound, discovered during prep for LSU talk.<commit_after>/*
 * Clipper
 * Extension Class for Jamoma DSP
 * Copyright © 2008, Timothy Place
 *
 * License: This code is licensed under the terms of the "New BSD License"
 * http://creativecommons.org/licenses/BSD/
 */

#include "TTDSP.h"

#define thisTTClass				Clipper
#define thisTTClassName			"clipper"
#define thisTTClassDescription	"Limits the amplitude of signals."
#define thisTTClassTags			"audio, processor"

/**	Hard-clip signals to a low and high bound. */

class Clipper : TTAudioObjectBase {
	TTCLASS_SETUP(Clipper)

	TTFloat64	mLowBound;		///< Attribute: low bound for clipping
	TTFloat64	mHighBound;		///< Attribute: high bound for clipping

	TTErr calculateValue(const TTFloat64& x, TTFloat64& y, TTPtrSizedInt channel)
	{
		y = x;
		TTLimit(y, mLowBound, mHighBound);
		return kTTErrNone;
	}

	/** Audio Processing Method */
	TTErr processAudio(TTAudioSignalArrayPtr inputs, TTAudioSignalArrayPtr outputs)
	{
		TT_WRAP_CALCULATE_METHOD(calculateValue);
	}
};

TT_AUDIO_CONSTRUCTOR_EXPORT(Clipper)
{
	addAttribute(		LowBound,	kTypeFloat64);
	addMessageProperty(	LowBound,	description,	TT("Sets the minimum amplitude."));

	addAttribute(		HighBound,	kTypeFloat64);
	addMessageProperty(	HighBound,	description,	TT("Sets the maximum amplitude."));

	setAttributeValue(TT("lowBound"), -1.0);
	setAttributeValue(TT("highBound"), 1.0);
	setProcessMethod(processAudio);
}

Clipper::~Clipper()
{;}
<|endoftext|>


<commit_before>/*
 * Copyright 2015 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi 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 BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Control.h"

#include <vector>
#include "Pid.h"
#include "defaultDevices.h"
#include "ActuatorInterfaces.h"
#include "ActuatorPwm.h"
#include "ActuatorTimeLimited.h"
#include "TempSensor.h"
#include "ActuatorSetPoint.h"
#include "ActuatorMutexDriver.h"
#include "ActuatorMutexGroup.h"
#include "json_writer.h"

Control::Control()
{
    // set up static devices for backwards compatibility with tempControl
    beer1Sensor = &defaultTempSensorBasic();
    beer2Sensor = &defaultTempSensorBasic();
    fridgeSensor = &defaultTempSensorBasic();

    beer1SensorNamed = new TempSensor(beer1Sensor, "beer1");
    beer2SensorNamed = new TempSensor(beer2Sensor, "beer2");
    fridgeSensorNamed = new TempSensor(fridgeSensor, "fridge");

    mutex = new ActuatorMutexGroup();

    heater1Pin = &defaultActuator();
    heater1Mutex = new ActuatorMutexDriver(heater1Pin, mutex);
    heater1 = new ActuatorPwm(heater1Mutex, 4); // period 4s

    heater2Pin = &defaultActuator();
    heater2Mutex = new ActuatorMutexDriver(heater1Pin, mutex);
    heater2 = new ActuatorPwm(heater2Mutex, 4); // period 4s

    coolerPin = &defaultActuator();
    coolerTimeLimited = new ActuatorTimeLimited(coolerPin, 120, 180); // 2 min minOn time, 3 min minOff
    coolerMutex = new ActuatorMutexDriver(coolerTimeLimited, mutex);
    cooler = new ActuatorPwm(coolerMutex, 900); // period 15 min

    beer1Set = new SetPointSimple();
    beer2Set = new SetPointSimple();
    fridgeSet = new SetPointSimple();

    fridgeSetPointActuator = new ActuatorSetPoint(fridgeSet, beer1Set);
    fridgeSetPointActuator->setMin(-10.0);
    fridgeSetPointActuator->setMax(10.0);

    heater1Pid = new Pid(fridgeSensor, heater1, fridgeSet);
    heater1Pid->setName("heater1");

    coolerPid = new Pid(fridgeSensor, cooler, fridgeSet);
    coolerPid->setActuatorIsNegative(true);
    coolerPid->setName("cooler");

    heater2Pid = new Pid(beer2Sensor, heater2, beer2Set);
    coolerPid->setName("heater2");

    beerToFridgePid = new Pid(beer1Sensor, fridgeSetPointActuator, beer1Set);
    beerToFridgePid->setName("beer2fridge");

    pids.push_back(heater1Pid);
    pids.push_back(heater2Pid);
    pids.push_back(coolerPid);
    pids.push_back(beerToFridgePid);

    sensors.push_back(fridgeSensorNamed);
    sensors.push_back(beer1SensorNamed);
    sensors.push_back(beer2SensorNamed);

    actuators.push_back(cooler);
    actuators.push_back(heater1);
    actuators.push_back(heater2);

    beer1SetNamed = new SetPointNamed(beer1Set, "beer1set");
    beer2SetNamed = new SetPointNamed(beer1Set, "beer2set");
    fridgeSetNamed = new SetPointNamed(beer1Set, "fridgeset");

    setpoints.push_back(beer1SetNamed);
    setpoints.push_back(beer2SetNamed);
    setpoints.push_back(fridgeSetNamed);

    mutex->setDeadTime(1800000); // 30 minutes
}

Control::~Control(){
    delete heater1Mutex;
    delete heater1;

    delete heater2Mutex;
    delete heater2;

    delete coolerTimeLimited;
    delete coolerMutex;
    delete cooler;

    delete fridgeSetPointActuator;

    delete beer1Set;
    delete beer2Set;
    delete fridgeSet;

    delete beer1SetNamed;
    delete beer2SetNamed;
    delete fridgeSetNamed;

    delete beer1SensorNamed;
    delete beer2SensorNamed;
    delete fridgeSensorNamed;

    delete mutex;

    delete heater1Pid;
    delete heater2Pid;
    delete coolerPid;
    delete beerToFridgePid;

    pids.clear();
    sensors.clear();
    actuators.clear();
}

void Control::update(){
    updateSensors();
    updatePids();
    updateActuators();
}

void Control::updatePids(){
    for ( auto &actuator : actuators ) {
        actuator->update();
    }
}

void Control::updateSensors(){
    for ( auto &sensor : sensors ) {
        sensor->update();
    }
}

void Control::updateActuators(){
    for ( auto &actuator : actuators ) {
        actuator->update();
    }
}

void Control::serialize(JSON::Adapter& adapter){
    JSON::Class root(adapter, "Control");
    JSON_E(adapter, pids);
    JSON_E(adapter, sensors);
    JSON_E(adapter, actuators);
    JSON_T(adapter, setpoints);
}

Control control;
<commit_msg>also update mutex group in actuators update<commit_after>/*
 * Copyright 2015 BrewPi/Elco Jacobs.
 *
 * This file is part of BrewPi.
 *
 * BrewPi is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * BrewPi 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 BrewPi.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "Control.h"

#include <vector>
#include "Pid.h"
#include "defaultDevices.h"
#include "ActuatorInterfaces.h"
#include "ActuatorPwm.h"
#include "ActuatorTimeLimited.h"
#include "TempSensor.h"
#include "ActuatorSetPoint.h"
#include "ActuatorMutexDriver.h"
#include "ActuatorMutexGroup.h"
#include "json_writer.h"

Control::Control()
{
    // set up static devices for backwards compatibility with tempControl
    beer1Sensor = &defaultTempSensorBasic();
    beer2Sensor = &defaultTempSensorBasic();
    fridgeSensor = &defaultTempSensorBasic();

    beer1SensorNamed = new TempSensor(beer1Sensor, "beer1");
    beer2SensorNamed = new TempSensor(beer2Sensor, "beer2");
    fridgeSensorNamed = new TempSensor(fridgeSensor, "fridge");

    mutex = new ActuatorMutexGroup();

    heater1Pin = &defaultActuator();
    heater1Mutex = new ActuatorMutexDriver(heater1Pin, mutex);
    heater1 = new ActuatorPwm(heater1Mutex, 4); // period 4s

    heater2Pin = &defaultActuator();
    heater2Mutex = new ActuatorMutexDriver(heater1Pin, mutex);
    heater2 = new ActuatorPwm(heater2Mutex, 4); // period 4s

    coolerPin = &defaultActuator();
    coolerTimeLimited = new ActuatorTimeLimited(coolerPin, 120, 180); // 2 min minOn time, 3 min minOff
    coolerMutex = new ActuatorMutexDriver(coolerTimeLimited, mutex);
    cooler = new ActuatorPwm(coolerMutex, 900); // period 15 min

    beer1Set = new SetPointSimple();
    beer2Set = new SetPointSimple();
    fridgeSet = new SetPointSimple();

    fridgeSetPointActuator = new ActuatorSetPoint(fridgeSet, beer1Set);
    fridgeSetPointActuator->setMin(-10.0);
    fridgeSetPointActuator->setMax(10.0);

    heater1Pid = new Pid(fridgeSensor, heater1, fridgeSet);
    heater1Pid->setName("heater1");

    coolerPid = new Pid(fridgeSensor, cooler, fridgeSet);
    coolerPid->setActuatorIsNegative(true);
    coolerPid->setName("cooler");

    heater2Pid = new Pid(beer2Sensor, heater2, beer2Set);
    coolerPid->setName("heater2");

    beerToFridgePid = new Pid(beer1Sensor, fridgeSetPointActuator, beer1Set);
    beerToFridgePid->setName("beer2fridge");

    pids.push_back(heater1Pid);
    pids.push_back(heater2Pid);
    pids.push_back(coolerPid);
    pids.push_back(beerToFridgePid);

    sensors.push_back(fridgeSensorNamed);
    sensors.push_back(beer1SensorNamed);
    sensors.push_back(beer2SensorNamed);

    actuators.push_back(cooler);
    actuators.push_back(heater1);
    actuators.push_back(heater2);

    beer1SetNamed = new SetPointNamed(beer1Set, "beer1set");
    beer2SetNamed = new SetPointNamed(beer1Set, "beer2set");
    fridgeSetNamed = new SetPointNamed(beer1Set, "fridgeset");

    setpoints.push_back(beer1SetNamed);
    setpoints.push_back(beer2SetNamed);
    setpoints.push_back(fridgeSetNamed);

    mutex->setDeadTime(1800000); // 30 minutes
}

Control::~Control(){
    delete heater1Mutex;
    delete heater1;

    delete heater2Mutex;
    delete heater2;

    delete coolerTimeLimited;
    delete coolerMutex;
    delete cooler;

    delete fridgeSetPointActuator;

    delete beer1Set;
    delete beer2Set;
    delete fridgeSet;

    delete beer1SetNamed;
    delete beer2SetNamed;
    delete fridgeSetNamed;

    delete beer1SensorNamed;
    delete beer2SensorNamed;
    delete fridgeSensorNamed;

    delete mutex;

    delete heater1Pid;
    delete heater2Pid;
    delete coolerPid;
    delete beerToFridgePid;

    pids.clear();
    sensors.clear();
    actuators.clear();
}

void Control::update(){
    updateSensors();
    updatePids();
    updateActuators();
}

void Control::updatePids(){
    for ( auto &actuator : actuators ) {
        actuator->update();
    }
}

void Control::updateSensors(){
    for ( auto &sensor : sensors ) {
        sensor->update();
    }
}

void Control::updateActuators(){
    for ( auto &actuator : actuators ) {
        actuator->update();
    }
    mutex->update();
}

void Control::serialize(JSON::Adapter& adapter){
    JSON::Class root(adapter, "Control");
    JSON_E(adapter, pids);
    JSON_E(adapter, sensors);
    JSON_E(adapter, actuators);
    JSON_T(adapter, setpoints);
}

Control control;
<|endoftext|>


<commit_before>//---------------------------------------------------------------------------
#pragma comment (lib, "gdi32.lib")

#include "DynDialogs.h"
//---------------------------------------------------------------------------

LPWORD DWORD_ALIGN(LPWORD lpIn)
{
   ULONG ul = (ULONG)lpIn;

   ul += 3;
   ul >>= 2;
   ul <<= 2;

   return (LPWORD)ul;
}
//---------------------------------------------------------------------------

LPWORD NON_DWORD_ALIGN(LPWORD lpIn)
{
   return (DWORD_ALIGN(lpIn - 1) + 1);
}
//---------------------------------------------------------------------------

LPWORD InitDialog(LPVOID lpv, LPCTSTR title, DWORD style, WORD ctrlno, LPCTSTR fontname,
                  WORD /*fontsize*/, short x, short y, short cx, short cy)
{
    LPWORD        lpw;
    LPWSTR        lpwsz;
    int           nchar, wcharlength;
    LPDLGTEMPLATE lpdt = (LPDLGTEMPLATE)lpv;

    lpdt->style = style;
    lpdt->dwExtendedStyle = 0;
    lpdt->cdit = ctrlno;
    lpdt->x  = x;  lpdt->y  = y;
    lpdt->cx = cx; lpdt->cy = cy;

    lpw = (LPWORD)(lpdt + 1);

    // No menu
    *lpw = 0;
    lpw++;

    // Predefined dialog box class (by default)
    *lpw = 0;
    lpw++;

    // The title
    lpwsz = (LPWSTR)lpw;
    wcharlength = MultiByteToWideChar(CP_ACP, 0, title, -1, lpwsz, 0);
    nchar = MultiByteToWideChar(CP_ACP, 0, title, -1, lpwsz, wcharlength);
    lpw += nchar;

    // The font used in dialog
    if(style & DS_SETFONT)
    {
       *lpw = 8;
       lpw++;
       lpwsz = (LPWSTR)lpw;
       wcharlength = MultiByteToWideChar(CP_ACP, 0, fontname, -1, lpwsz, 0);
       nchar = MultiByteToWideChar(CP_ACP, 0, fontname, -1, lpwsz, wcharlength);
       lpw += nchar;
    }

    return lpw;
}
//---------------------------------------------------------------------------

LPWORD CreateDlgControl(LPWORD lpw, WORD ctrlclass, WORD id, LPCTSTR caption,
                      DWORD style, short x, short y, short cx, short cy)
{
    LPDLGITEMTEMPLATE lpdit;
    LPWSTR            lpwsz;
    int               nchar, wcharlength;

    lpw = DWORD_ALIGN(lpw);
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->style = style;
    lpdit->dwExtendedStyle = 0;
    lpdit->x  = x ; lpdit->y  = y;
    lpdit->cx = cx; lpdit->cy = cy;
    lpdit->id = id;

    // class
    lpw = (LPWORD)(lpdit + 1);
    *lpw = 0xFFFF;
    lpw++;
    *lpw = ctrlclass;
    lpw++;

    // title
    lpwsz = (LPWSTR)lpw;
    wcharlength = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, 0);
    nchar = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, wcharlength);
    lpw += nchar;

    // no creation data
    lpw = NON_DWORD_ALIGN(lpw);
    *lpw = 0;
    lpw++;

    return lpw;
}
//---------------------------------------------------------------------------

int InputBox(HWND hwnd, LPCTSTR prompt, LPCTSTR title, LPTSTR buffer, INT buflength)
{
    HGLOBAL  hgbl;
    LPWORD   lpw;
    LRESULT  ret;
    DWORD    style;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    if(!hgbl) return 0;
    LPVOID lpv = GlobalLock(hgbl);

    // Prepare the dialog box
    style = DS_SETFONT | DS_CENTER | DS_3DLOOK | WS_POPUP | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | WS_VISIBLE;
    lpw = InitDialog(lpv, title, style, 4, "MS Sans Serif", 8, 0, 0, 319, 47);

    // OK-Button
    style = WS_CHILD | WS_VISIBLE | WS_TABSTOP |BS_DEFPUSHBUTTON;
    lpw = CreateDlgControl(lpw, BUTTON_CLASS, IDOK, "OK", style, 264, 7, 48, 15);

    // Cancel-Button
    style = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON;
    lpw = CreateDlgControl(lpw, BUTTON_CLASS, IDCANCEL, "Abbrechen", style, 264, 26, 48, 15);

    // Text to prompt
    style = WS_CHILD | WS_VISIBLE | SS_LEFT;
    lpw = CreateDlgControl(lpw, STATIC_CLASS, ID_INFOTEXT, prompt, style, 10, 9, 129, 16);

    // Edit-Control
    style = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP;
    lpw = CreateDlgControl(lpw, EDIT_CLASS, ID_INPUT, "", style, 10, 26, 249, 13);

    GlobalUnlock(hgbl);
    int data[2] = {(int)buffer, buflength};
    ret = DialogBoxIndirectParamA(NULL, (LPDLGTEMPLATE)hgbl, hwnd,
                                 (DLGPROC)InputBoxDlgProc, (int)data);
    GlobalFree(hgbl);
    return (ret > 0) ? ret : 0;
}
//---------------------------------------------------------------------------

BOOL CALLBACK InputBoxDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
   static char* buf;
   static int   buflength;
   static HFONT hFont;

   switch(uiMsg)
   {
      case WM_INITDIALOG:
      {
         int* data = (int*)lParam;
         buf = (char*)data[0];
         buflength = data[1];
         HWND hEdit = GetDlgItem(hwnd, ID_INPUT);
         SetFocus(hEdit);
         break;
      }

      case WM_SETFONT:
         hFont = (HFONT)wParam;
         break;

      case WM_CLOSE:
         EndDialog(hwnd, IDCANCEL);
         DeleteObject(hFont);
         break;

      case WM_COMMAND:
      {
         switch(LOWORD(wParam))
         {
            case IDOK:
            {
               HWND hEdit = GetDlgItem(hwnd, ID_INPUT);
               GetWindowText(hEdit, buf, buflength);
               EndDialog(hwnd, IDOK);
               DeleteObject(hFont);
               break;
            }

            case IDCANCEL:
            {
               EndDialog(hwnd, IDCANCEL);
               break;
            }
         }
      }
   }
   return FALSE;
}
//---------------------------------------------------------------------------

VOID ShowMessage(HWND hwnd, LPCTSTR lpszMsg, LPCTSTR lpszTitle, WORD wIcon)
{
   UINT uType = 0;
   if(wIcon == SM_WARNING)
      uType = MB_ICONWARNING;
   else if(wIcon == SM_INFO)
      uType = MB_ICONINFORMATION;
   else if(wIcon == SM_ERROR)
      uType = MB_ICONERROR;

   MessageBox(hwnd, lpszMsg, lpszTitle, uType);
}
//---------------------------------------------------------------------------<commit_msg>TIScam: Prevent VC++ x64 warning.<commit_after>//---------------------------------------------------------------------------
#pragma comment (lib, "gdi32.lib")

#include "DynDialogs.h"
//---------------------------------------------------------------------------

LPWORD DWORD_ALIGN(LPWORD lpIn)
{
   ULONG ul = (ULONG)lpIn;

   ul += 3;
   ul >>= 2;
   ul <<= 2;

   return (LPWORD)ul;
}
//---------------------------------------------------------------------------

LPWORD NON_DWORD_ALIGN(LPWORD lpIn)
{
   return (DWORD_ALIGN(lpIn - 1) + 1);
}
//---------------------------------------------------------------------------

LPWORD InitDialog(LPVOID lpv, LPCTSTR title, DWORD style, WORD ctrlno, LPCTSTR fontname,
                  WORD /*fontsize*/, short x, short y, short cx, short cy)
{
    LPWORD        lpw;
    LPWSTR        lpwsz;
    int           nchar, wcharlength;
    LPDLGTEMPLATE lpdt = (LPDLGTEMPLATE)lpv;

    lpdt->style = style;
    lpdt->dwExtendedStyle = 0;
    lpdt->cdit = ctrlno;
    lpdt->x  = x;  lpdt->y  = y;
    lpdt->cx = cx; lpdt->cy = cy;

    lpw = (LPWORD)(lpdt + 1);

    // No menu
    *lpw = 0;
    lpw++;

    // Predefined dialog box class (by default)
    *lpw = 0;
    lpw++;

    // The title
    lpwsz = (LPWSTR)lpw;
    wcharlength = MultiByteToWideChar(CP_ACP, 0, title, -1, lpwsz, 0);
    nchar = MultiByteToWideChar(CP_ACP, 0, title, -1, lpwsz, wcharlength);
    lpw += nchar;

    // The font used in dialog
    if(style & DS_SETFONT)
    {
       *lpw = 8;
       lpw++;
       lpwsz = (LPWSTR)lpw;
       wcharlength = MultiByteToWideChar(CP_ACP, 0, fontname, -1, lpwsz, 0);
       nchar = MultiByteToWideChar(CP_ACP, 0, fontname, -1, lpwsz, wcharlength);
       lpw += nchar;
    }

    return lpw;
}
//---------------------------------------------------------------------------

LPWORD CreateDlgControl(LPWORD lpw, WORD ctrlclass, WORD id, LPCTSTR caption,
                      DWORD style, short x, short y, short cx, short cy)
{
    LPDLGITEMTEMPLATE lpdit;
    LPWSTR            lpwsz;
    int               nchar, wcharlength;

    lpw = DWORD_ALIGN(lpw);
    lpdit = (LPDLGITEMTEMPLATE)lpw;
    lpdit->style = style;
    lpdit->dwExtendedStyle = 0;
    lpdit->x  = x ; lpdit->y  = y;
    lpdit->cx = cx; lpdit->cy = cy;
    lpdit->id = id;

    // class
    lpw = (LPWORD)(lpdit + 1);
    *lpw = 0xFFFF;
    lpw++;
    *lpw = ctrlclass;
    lpw++;

    // title
    lpwsz = (LPWSTR)lpw;
    wcharlength = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, 0);
    nchar = MultiByteToWideChar(CP_ACP, 0, caption, -1, lpwsz, wcharlength);
    lpw += nchar;

    // no creation data
    lpw = NON_DWORD_ALIGN(lpw);
    *lpw = 0;
    lpw++;

    return lpw;
}
//---------------------------------------------------------------------------

int InputBox(HWND hwnd, LPCTSTR prompt, LPCTSTR title, LPTSTR buffer, INT buflength)
{
    HGLOBAL  hgbl;
    LPWORD   lpw;
    LRESULT  ret;
    DWORD    style;

    hgbl = GlobalAlloc(GMEM_ZEROINIT, 1024);
    if(!hgbl) return 0;
    LPVOID lpv = GlobalLock(hgbl);

    // Prepare the dialog box
    style = DS_SETFONT | DS_CENTER | DS_3DLOOK | WS_POPUP | WS_SYSMENU | DS_MODALFRAME | WS_CAPTION | WS_VISIBLE;
    lpw = InitDialog(lpv, title, style, 4, "MS Sans Serif", 8, 0, 0, 319, 47);

    // OK-Button
    style = WS_CHILD | WS_VISIBLE | WS_TABSTOP |BS_DEFPUSHBUTTON;
    lpw = CreateDlgControl(lpw, BUTTON_CLASS, IDOK, "OK", style, 264, 7, 48, 15);

    // Cancel-Button
    style = WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_PUSHBUTTON;
    lpw = CreateDlgControl(lpw, BUTTON_CLASS, IDCANCEL, "Abbrechen", style, 264, 26, 48, 15);

    // Text to prompt
    style = WS_CHILD | WS_VISIBLE | SS_LEFT;
    lpw = CreateDlgControl(lpw, STATIC_CLASS, ID_INFOTEXT, prompt, style, 10, 9, 129, 16);

    // Edit-Control
    style = WS_CHILD | WS_VISIBLE | WS_BORDER | WS_TABSTOP;
    lpw = CreateDlgControl(lpw, EDIT_CLASS, ID_INPUT, "", style, 10, 26, 249, 13);

    GlobalUnlock(hgbl);
    int data[2] = {(int)buffer, buflength};
    ret = DialogBoxIndirectParamA(NULL, (LPDLGTEMPLATE)hgbl, hwnd,
                                 (DLGPROC)InputBoxDlgProc, (int)data);
    GlobalFree(hgbl);
    return static_cast<int>((ret > 0) ? ret : 0);
}
//---------------------------------------------------------------------------

BOOL CALLBACK InputBoxDlgProc(HWND hwnd, UINT uiMsg, WPARAM wParam, LPARAM lParam)
{
   static char* buf;
   static int   buflength;
   static HFONT hFont;

   switch(uiMsg)
   {
      case WM_INITDIALOG:
      {
         int* data = (int*)lParam;
         buf = (char*)data[0];
         buflength = data[1];
         HWND hEdit = GetDlgItem(hwnd, ID_INPUT);
         SetFocus(hEdit);
         break;
      }

      case WM_SETFONT:
         hFont = (HFONT)wParam;
         break;

      case WM_CLOSE:
         EndDialog(hwnd, IDCANCEL);
         DeleteObject(hFont);
         break;

      case WM_COMMAND:
      {
         switch(LOWORD(wParam))
         {
            case IDOK:
            {
               HWND hEdit = GetDlgItem(hwnd, ID_INPUT);
               GetWindowText(hEdit, buf, buflength);
               EndDialog(hwnd, IDOK);
               DeleteObject(hFont);
               break;
            }

            case IDCANCEL:
            {
               EndDialog(hwnd, IDCANCEL);
               break;
            }
         }
      }
   }
   return FALSE;
}
//---------------------------------------------------------------------------

VOID ShowMessage(HWND hwnd, LPCTSTR lpszMsg, LPCTSTR lpszTitle, WORD wIcon)
{
   UINT uType = 0;
   if(wIcon == SM_WARNING)
      uType = MB_ICONWARNING;
   else if(wIcon == SM_INFO)
      uType = MB_ICONINFORMATION;
   else if(wIcon == SM_ERROR)
      uType = MB_ICONERROR;

   MessageBox(hwnd, lpszMsg, lpszTitle, uType);
}
//---------------------------------------------------------------------------<|endoftext|>