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

#ifndef _FAIR_MESSAGE_QUEUE_HPP_
#define _FAIR_MESSAGE_QUEUE_HPP_

#include "Time.hpp"

namespace CBR {

class Message;
class Server;
namespace QueueEnum {
    enum PushResult {
        PushSucceeded,
        PushExceededMaximumSize
    };
};
template <typename Message> class Queue {
    std::deque<Message> mMessages;
    uint32 mMaxSize;
public:
    Queue(uint32 max_size){
        mMaxSize=max_size;
    }
    ~Queue(){}

    QueueEnum::PushResult push(const Message &msg){
        if (mMessages.size()>=mMaxSize)
            return QueueEnum::PushExceededMaximumSize;
        mMessages.push_back(msg);
        return QueueEnum::PushSucceeded;
    }

    const Message& front() const{
        return mMessages.front();
    }
    Message& front() {
        return mMessages.front();
    }
    Message pop(){
        Message m;
        std::swap(m,mMessages.front());
        mMessages.pop_front();
        return m;
    }
    bool empty() const{
        return mMessages.empty();
    }
};

template<class MessageQueue> class Weight {
public:
    uint32 operator()(const MessageQueue&mq)const {
        return mq.front()->size();
    }
};
template <class Message,class Key,class WeightFunction=Weight<Queue<Message*> > > class FairMessageQueue {
public:
    struct ServerQueueInfo {
        ServerQueueInfo():nextFinishTime(0) {
            messageQueue=NULL;
            weight=1.0;
        }
        ServerQueueInfo(Queue<Message*>* queue, float w)
         : messageQueue(queue), weight(w), nextFinishTime(0) {}

        Queue<Message*>* messageQueue;
        float weight;
        Time nextFinishTime;
    };

    typedef std::map<Key, ServerQueueInfo> ServerQueueInfoMap;

    typedef Queue<Message*> MessageQueue;
    FairMessageQueue(uint32 bytes_per_second)
        : mRate(bytes_per_second),
         mTotalWeight(0),
         mCurrentTime(0),
         mCurrentVirtualTime(0),
         mMessageBeingSent(NULL),
         mMessageSendFinishTime(0),
         mServerQueues(),
         bytes_sent(0){}

    ~FairMessageQueue(){
        typename ServerQueueInfoMap::iterator it = mServerQueues.begin();
        for(; it != mServerQueues.end(); it++) {
            ServerQueueInfo* queue_info = &it->second;
            delete queue_info->messageQueue;
        }
    }

    void addQueue(MessageQueue *mq, Key server, float weight){
        assert(mq->empty());

        ServerQueueInfo queue_info (mq, weight);

        mTotalWeight += weight;
        mServerQueues[server] = queue_info;
    }
    bool removeQueue(Key server) {
        typename ServerQueueInfoMap::iterator where=mServerQueues.find(server);
        bool retval=( where != mServerQueues.end() );
        if (retval) {
            delete where->second.messageQueue;
            mServerQueues.erase(where);
        }
        return retval;
    }
    bool hasQueue(Key server) const{
        return ( mServerQueues.find(server) != mServerQueues.end() );
    }

    QueueEnum::PushResult queueMessage(Key dest_server, Message *msg){
        typename ServerQueueInfoMap::iterator qi_it = mServerQueues.find(dest_server);

        assert( qi_it != mServerQueues.end() );

        ServerQueueInfo* queue_info = &qi_it->second;

        if (queue_info->messageQueue->empty())
            queue_info->nextFinishTime = finishTime(msg->size(), queue_info->weight);

        return queue_info->messageQueue->push(msg);
    }

    // returns a list of messages which should be delivered immediately
    std::vector<Message*> tick(const Time& t){
        Duration since_last = t - mCurrentTime;
        mCurrentTime = t;

        std::vector<Message*> msgs;

        bool processed_message = true;
        while( processed_message == true ) {
            processed_message = false;

            // If we are currently working on delivering a message, check if it can now be delivered
            if (mMessageBeingSent != NULL) {
                if ( mCurrentTime > mMessageSendFinishTime ) {
                    msgs.push_back(mMessageBeingSent);
                    mMessageBeingSent = NULL;
                    processed_message = true;
                }
            } else {
                // with no processing, update the last finish time to the current time so we don't use
                // past time for processing a new message
                mMessageSendFinishTime = mCurrentTime;
            }

            // If no message is currently being processed (or we just finished processing one), check for
            // another message to process
            if (mMessageBeingSent == NULL) {
                // Find the non-empty queue with the earliest finish time
                ServerQueueInfo* min_queue_info = NULL;
                for(typename ServerQueueInfoMap::iterator it = mServerQueues.begin(); it != mServerQueues.end(); it++) {
                    ServerQueueInfo* queue_info = &it->second;
                    if (queue_info->messageQueue->empty()) continue;
                    if (min_queue_info == NULL || queue_info->nextFinishTime < min_queue_info->nextFinishTime)
                        min_queue_info = queue_info;
                }

                // If we actually have something to deliver, deliver it
                if (min_queue_info) {
                    mCurrentVirtualTime = min_queue_info->nextFinishTime;
                    mMessageBeingSent = min_queue_info->messageQueue->pop();

                    uint32 message_size = mMessageBeingSent->size();
                    Duration duration_to_finish_send = Duration::milliseconds(message_size / (mRate/1000.f));
                    mMessageSendFinishTime = mMessageSendFinishTime + duration_to_finish_send;

                    // update the next finish time if there's anything in the queue
                    if (!min_queue_info->messageQueue->empty())
                        min_queue_info->nextFinishTime = finishTime(WeightFunction()(*min_queue_info->messageQueue), min_queue_info->weight);
                }
            }
        }

        if (msgs.size() > 0) {
            for(uint32 k = 0; k < msgs.size(); k++) {
                bytes_sent += msgs[k]->size();
            }
            Duration since_start = mCurrentTime - Time(0);
            printf("%d / %f = %f bytes per second\n", bytes_sent, since_start.seconds(), bytes_sent / since_start.seconds());
        }

        return msgs;
    }
private:
    // because I *CAN*
    Time FinnishTime(uint32 size, float weight) const{
        return finishTime(size,weight);
    }
    Time finishTime(uint32 size, float weight) const{
        float queue_frac = weight / mTotalWeight;
        Duration transmitTime = Duration::seconds( size / (mRate * queue_frac) );
        if (transmitTime == Duration(0)) transmitTime = Duration(1); // just make sure we take *some* time

        return mCurrentVirtualTime + transmitTime;
    }

    uint32 mRate;
    uint32 mTotalWeight;
    Time mCurrentTime;
    Time mCurrentVirtualTime;
    Message *mMessageBeingSent;
    Time mMessageSendFinishTime;
    ServerQueueInfoMap mServerQueues;

    uint32 bytes_sent;
}; // class FairMessageQueue

} // namespace Cobra

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

#ifndef _FAIR_MESSAGE_QUEUE_HPP_
#define _FAIR_MESSAGE_QUEUE_HPP_

#include "Time.hpp"

namespace CBR {

class Message;
class Server;
namespace QueueEnum {
    enum PushResult {
        PushSucceeded,
        PushExceededMaximumSize
    };
};
template <typename Message> class Queue {
    std::deque<Message> mMessages;
    uint32 mMaxSize;
public:
    Queue(uint32 max_size){
        mMaxSize=max_size;
    }
    ~Queue(){}

    QueueEnum::PushResult push(const Message &msg){
        if (mMessages.size()>=mMaxSize)
            return QueueEnum::PushExceededMaximumSize;
        mMessages.push_back(msg);
        return QueueEnum::PushSucceeded;
    }

    const Message& front() const{
        return mMessages.front();
    }
    Message& front() {
        return mMessages.front();
    }
    Message pop(){
        Message m;
        std::swap(m,mMessages.front());
        mMessages.pop_front();
        return m;
    }
    bool empty() const{
        return mMessages.empty();
    }
};

template<class MessageQueue> class Weight {
public:
    uint32 operator()(const MessageQueue&mq)const {
        return mq.front()->size();
    }
};
template <class Message,class Key,class WeightFunction=Weight<Queue<Message*> > > class FairMessageQueue {
public:
    struct ServerQueueInfo {
        ServerQueueInfo():nextFinishTime(0) {
            messageQueue=NULL;
            weight=1.0;
        }
        ServerQueueInfo(Queue<Message*>* queue, float w)
         : messageQueue(queue), weight(w), nextFinishTime(0) {}

        Queue<Message*>* messageQueue;
        float weight;
        Time nextFinishTime;
    };

    typedef std::map<Key, ServerQueueInfo> ServerQueueInfoMap;

    typedef Queue<Message*> MessageQueue;
    FairMessageQueue(uint32 bytes_per_second)
        : mRate(bytes_per_second),
         mTotalWeight(0),
         mCurrentTime(0),
         mCurrentVirtualTime(0),
         mMessageBeingSent(NULL),
         mMessageSendFinishTime(0),
         mServerQueues(),
         bytes_sent(0){}

    ~FairMessageQueue(){
        typename ServerQueueInfoMap::iterator it = mServerQueues.begin();
        for(; it != mServerQueues.end(); it++) {
            ServerQueueInfo* queue_info = &it->second;
            delete queue_info->messageQueue;
        }
    }

    void addQueue(MessageQueue *mq, Key server, float weight){
        assert(mq->empty());

        ServerQueueInfo queue_info (mq, weight);

        mTotalWeight += weight;
        mServerQueues[server] = queue_info;
    }
    bool removeQueue(Key server) {
        typename ServerQueueInfoMap::iterator where=mServerQueues.find(server);
        bool retval=( where != mServerQueues.end() );
        if (retval) {
            delete where->second.messageQueue;
            mServerQueues.erase(where);
        }
        return retval;
    }
    bool hasQueue(Key server) const{
        return ( mServerQueues.find(server) != mServerQueues.end() );
    }

    QueueEnum::PushResult queueMessage(Key dest_server, Message *msg){
        typename ServerQueueInfoMap::iterator qi_it = mServerQueues.find(dest_server);

        assert( qi_it != mServerQueues.end() );

        ServerQueueInfo* queue_info = &qi_it->second;

        if (queue_info->messageQueue->empty())
            queue_info->nextFinishTime = finishTime(msg->size(), queue_info->weight);

        return queue_info->messageQueue->push(msg);
    }

    // returns a list of messages which should be delivered immediately
    std::vector<Message*> tick(const Time& t){
        Duration since_last = t - mCurrentTime;
        mCurrentTime = t;

        std::vector<Message*> msgs;

        bool processed_message = true;
        while( processed_message == true ) {
            processed_message = false;

            // If we are currently working on delivering a message, check if it can now be delivered
            if (mMessageBeingSent != NULL) {
                if ( mCurrentTime > mMessageSendFinishTime ) {
                    msgs.push_back(mMessageBeingSent);
                    mMessageBeingSent = NULL;
                    processed_message = true;
                }
            } else {
                // with no processing, update the last finish time to the current time so we don't use
                // past time for processing a new message
                mMessageSendFinishTime = mCurrentTime;
            }

            // If no message is currently being processed (or we just finished processing one), check for
            // another message to process
            if (mMessageBeingSent == NULL) {
                // Find the non-empty queue with the earliest finish time
                ServerQueueInfo* min_queue_info = NULL;
                for(typename ServerQueueInfoMap::iterator it = mServerQueues.begin(); it != mServerQueues.end(); it++) {
                    ServerQueueInfo* queue_info = &it->second;
                    if (queue_info->messageQueue->empty()) continue;
                    if (min_queue_info == NULL || queue_info->nextFinishTime < min_queue_info->nextFinishTime)
                        min_queue_info = queue_info;
                }

                // If we actually have something to deliver, deliver it
                if (min_queue_info) {
                    mCurrentVirtualTime = min_queue_info->nextFinishTime;
                    mMessageBeingSent = min_queue_info->messageQueue->pop();

                    uint32 message_size = mMessageBeingSent->size();
                    Duration duration_to_finish_send = Duration::milliseconds(message_size / (mRate/1000.f));
                    mMessageSendFinishTime = mMessageSendFinishTime + duration_to_finish_send;

                    // update the next finish time if there's anything in the queue
                    if (!min_queue_info->messageQueue->empty())
                        min_queue_info->nextFinishTime = finishTime(WeightFunction()(*min_queue_info->messageQueue), min_queue_info->weight);
                }
            }
        }

        if (msgs.size() > 0) {
            for(uint32 k = 0; k < msgs.size(); k++) {
                bytes_sent += msgs[k]->size();
            }
            Duration since_start = mCurrentTime - Time(0);
            //printf("%d / %f = %f bytes per second\n", bytes_sent, since_start.seconds(), bytes_sent / since_start.seconds());
        }

        return msgs;
    }
private:
    // because I *CAN*
    Time FinnishTime(uint32 size, float weight) const{
        return finishTime(size,weight);
    }
    Time finishTime(uint32 size, float weight) const{
        float queue_frac = weight / mTotalWeight;
        Duration transmitTime = Duration::seconds( size / (mRate * queue_frac) );
        if (transmitTime == Duration(0)) transmitTime = Duration(1); // just make sure we take *some* time

        return mCurrentVirtualTime + transmitTime;
    }

    uint32 mRate;
    uint32 mTotalWeight;
    Time mCurrentTime;
    Time mCurrentVirtualTime;
    Message *mMessageBeingSent;
    Time mMessageSendFinishTime;
    ServerQueueInfoMap mServerQueues;

    uint32 bytes_sent;
}; // class FairMessageQueue

} // namespace Cobra

#endif //_FAIR_MESSAGE_QUEUE_HPP_
<|endoftext|>


<commit_before>/*
Copyright 2015 Esri

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.

A local copy of the license and additional notices are located with the
source distribution at:

http://github.com/Esri/lerc/

Contributors:  Thomas Maurer
*/

#include "Defines.h"
#include "BitMask.h"
#include <cstring>

USING_NAMESPACE_LERC

// -------------------------------------------------------------------------- ;

BitMask::BitMask(const BitMask& src) : m_pBits(nullptr)
{
  SetSize(src.m_nCols, src.m_nRows);
  if (m_pBits && src.m_pBits)
    memcpy(m_pBits, src.m_pBits, Size());
}

// -------------------------------------------------------------------------- ;

BitMask& BitMask::operator= (const BitMask& src)
{
  if (this == &src) return *this;

  SetSize(src.m_nCols, src.m_nRows);
  if (m_pBits && src.m_pBits)
    memcpy(m_pBits, src.m_pBits, Size());

  return *this;
}

// -------------------------------------------------------------------------- ;

void BitMask::SetAllValid() const
{
  memset(m_pBits, 255, Size());
}

void BitMask::SetAllInvalid() const
{
  memset(m_pBits, 0, Size());
}

// -------------------------------------------------------------------------- ;

bool BitMask::SetSize(int nCols, int nRows)
{
  if (nCols != m_nCols || nRows != m_nRows)
  {
    Clear();
    m_pBits = new Byte[(nCols * nRows + 7) >> 3];
    if (m_pBits)
    {
      m_nCols = nCols;
      m_nRows = nRows;
    }
  }
  return m_pBits != nullptr;
}

// -------------------------------------------------------------------------- ;

int BitMask::CountValidBits() const
{
  const Byte numBitsHB[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  const Byte* ptr = m_pBits;
  int sum = 0;
  int i = Size();
  while (i--)
  {
    sum += numBitsHB[*ptr & 15] + numBitsHB[*ptr >> 4];
    ptr++;
  }

  // subtract undefined bits potentially contained in the last byte
  for (int k = m_nCols * m_nRows; k < Size() * 8; k++)
    if (IsValid(k))
      sum--;

  return sum;
}

// -------------------------------------------------------------------------- ;

void BitMask::Clear()
{
  delete[] m_pBits;
  m_pBits = nullptr;
  m_nCols = 0;
  m_nRows = 0;
}

// -------------------------------------------------------------------------- ;

<commit_msg>tmaurer3/harden_bitmask_setsize<commit_after>/*
Copyright 2015 Esri

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.

A local copy of the license and additional notices are located with the
source distribution at:

http://github.com/Esri/lerc/

Contributors:  Thomas Maurer
*/

#include "Defines.h"
#include "BitMask.h"
#include <cstring>

USING_NAMESPACE_LERC

// -------------------------------------------------------------------------- ;

BitMask::BitMask(const BitMask& src) : m_pBits(nullptr), m_nCols(0), m_nRows(0)
{
  SetSize(src.m_nCols, src.m_nRows);
  if (m_pBits && src.m_pBits)
    memcpy(m_pBits, src.m_pBits, Size());
}

// -------------------------------------------------------------------------- ;

BitMask& BitMask::operator= (const BitMask& src)
{
  if (this == &src) return *this;

  SetSize(src.m_nCols, src.m_nRows);
  if (m_pBits && src.m_pBits)
    memcpy(m_pBits, src.m_pBits, Size());

  return *this;
}

// -------------------------------------------------------------------------- ;

void BitMask::SetAllValid() const
{
  memset(m_pBits, 255, Size());
}

void BitMask::SetAllInvalid() const
{
  memset(m_pBits, 0, Size());
}

// -------------------------------------------------------------------------- ;

bool BitMask::SetSize(int nCols, int nRows)
{
  if (nCols <= 0 || nRows <= 0)
  {
    Clear();
    return (nCols == 0 && nRows == 0);
  }

  if (nCols != m_nCols || nRows != m_nRows)
  {
    Clear();

    try
    {
      size_t nPix = (size_t)nCols * (size_t)nRows;
      m_pBits = new Byte[(nPix + 7) >> 3];
    }
    catch (...)
    {
      return false;
    }

    if (!m_pBits)
      return false;

    m_nCols = nCols;
    m_nRows = nRows;
  }

  return m_pBits != nullptr;
}

// -------------------------------------------------------------------------- ;

int BitMask::CountValidBits() const
{
  const Byte numBitsHB[16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
  const Byte* ptr = m_pBits;
  int sum = 0;
  int i = Size();
  while (i--)
  {
    sum += numBitsHB[*ptr & 15] + numBitsHB[*ptr >> 4];
    ptr++;
  }

  // subtract undefined bits potentially contained in the last byte
  for (int k = m_nCols * m_nRows; k < Size() * 8; k++)
    if (IsValid(k))
      sum--;

  return sum;
}

// -------------------------------------------------------------------------- ;

void BitMask::Clear()
{
  delete[] m_pBits;
  m_pBits = nullptr;
  m_nCols = 0;
  m_nRows = 0;
}

// -------------------------------------------------------------------------- ;

<|endoftext|>


<commit_before>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmlstandaloneappwizard.h"
#include "qmlstandaloneappwizardpages.h"
#include "qmlstandaloneapp.h"

#include "qmlprojectconstants.h"

#include <projectexplorer/baseprojectwizarddialog.h>
#include <projectexplorer/customwizard/customwizard.h>
#include <projectexplorer/projectexplorer.h>
#include <coreplugin/editormanager/editormanager.h>

#include <QtGui/QIcon>

#include <QtGui/QPainter>
#include <QtGui/QPixmap>

#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFile>

namespace QmlProjectManager {
namespace Internal {

class QmlStandaloneAppWizardDialog : public ProjectExplorer::BaseProjectWizardDialog
{
    Q_OBJECT

public:
    explicit QmlStandaloneAppWizardDialog(QmlStandaloneAppWizard::WizardType type, QWidget *parent = 0);

private:
    QmlStandaloneAppWizard::WizardType m_type;
    class QmlStandaloneAppWizardSourcesPage *m_qmlSourcesPage;
    class QmlStandaloneAppWizardOptionsPage *m_qmlOptionsPage;
    friend class QmlStandaloneAppWizard;
};

QmlStandaloneAppWizardDialog::QmlStandaloneAppWizardDialog(QmlStandaloneAppWizard::WizardType type,
                                                           QWidget *parent)
    : ProjectExplorer::BaseProjectWizardDialog(parent)
    , m_type(type)
{
    setWindowTitle(m_type == QmlStandaloneAppWizard::NewQmlFile
                       ? tr("New Standalone QML Project")
                       : tr("Standalone QML Project from existing QML Project"));
    setIntroDescription(m_type == QmlStandaloneAppWizard::NewQmlFile
                       ? tr("This wizard generates a Standalone QML application project.")
                       : tr("This wizard imports an existing QML application and creates a standalone version of it."));

    m_qmlSourcesPage = new QmlStandaloneAppWizardSourcesPage;
    m_qmlSourcesPage->setMainQmlFileChooserVisible(m_type == QmlStandaloneAppWizard::ImportQmlFile);
    if (m_type == QmlStandaloneAppWizard::ImportQmlFile) {
        const int qmlSourcesPagePageId = addPage(m_qmlSourcesPage);
        wizardProgress()->item(qmlSourcesPagePageId)->setTitle(tr("Qml Sources"));
    }

    m_qmlOptionsPage = new QmlStandaloneAppWizardOptionsPage;
    const int qmlOptionsPagePageId = addPage(m_qmlOptionsPage);
    wizardProgress()->item(qmlOptionsPagePageId)->setTitle(tr("Qml App options"));
}

class QmlStandaloneAppWizardPrivate
{
    QmlStandaloneAppWizard::WizardType type;
    class QmlStandaloneApp *standaloneApp;
    class QmlStandaloneAppWizardDialog *wizardDialog;
    friend class QmlStandaloneAppWizard;
};

QmlStandaloneAppWizard::QmlStandaloneAppWizard(WizardType type)
    : Core::BaseFileWizard(parameters(type))
    , m_d(new QmlStandaloneAppWizardPrivate)
{
    m_d->type = type;
    m_d->standaloneApp = new QmlStandaloneApp;
    m_d->wizardDialog = 0;
}

QmlStandaloneAppWizard::~QmlStandaloneAppWizard()
{
    delete m_d->standaloneApp;
}

Core::BaseFileWizardParameters QmlStandaloneAppWizard::parameters(WizardType type)
{
    Core::BaseFileWizardParameters parameters(ProjectWizard);
    parameters.setIcon(QIcon(QLatin1String(Constants::QML_WIZARD_ICON)));
    parameters.setDisplayName(type == QmlStandaloneAppWizard::NewQmlFile
                              ? tr("Qt QML New Standalone Application")
                              : tr("Qt QML Imported Standalone Application"));
    parameters.setId(QLatin1String(type == QmlStandaloneAppWizard::NewQmlFile
                                   ? "QA.QML New Standalone Application"
                                   : "QA.QML Imported Standalone Application"));
    parameters.setDescription(type == QmlStandaloneAppWizard::NewQmlFile
                              ? tr("Creates a standalone, mobile-deployable Qt QML application "
                                   "project. A lightweight Qt/C++ application with a QDeclarativeView "
                                   "and a single QML file will be created.")
                              : tr("Creates a standalone, mobile-deployable Qt QML application "
                                   "project. An erxisting QML project will be imported and a lightweight "
                                   "Qt/C++ application with a QDeclarativeView will be created for it."));
    parameters.setCategory(QLatin1String(Constants::QML_WIZARD_CATEGORY));
    parameters.setDisplayCategory(QCoreApplication::translate(Constants::QML_WIZARD_TR_SCOPE,
                                                              Constants::QML_WIZARD_TR_CATEGORY));
    return parameters;
}

QWizard *QmlStandaloneAppWizard::createWizardDialog(QWidget *parent,
                                                    const QString &defaultPath,
                                                    const WizardPageList &extensionPages) const
{
    m_d->wizardDialog = new QmlStandaloneAppWizardDialog(m_d->type, parent);

    m_d->wizardDialog->setPath(defaultPath);
    m_d->wizardDialog->setProjectName(QmlStandaloneAppWizardDialog::uniqueProjectName(defaultPath));
    m_d->wizardDialog->m_qmlOptionsPage->setSymbianSvgIcon(m_d->standaloneApp->symbianSvgIcon());
    m_d->wizardDialog->m_qmlOptionsPage->setOrientation(m_d->standaloneApp->orientation());
    m_d->wizardDialog->m_qmlOptionsPage->setNetworkEnabled(m_d->standaloneApp->networkEnabled());
    m_d->wizardDialog->m_qmlOptionsPage->setLoadDummyData(m_d->standaloneApp->loadDummyData());
    connect(m_d->wizardDialog, SIGNAL(introPageLeft(QString, QString)), SLOT(useProjectPath(QString, QString)));

    foreach (QWizardPage *p, extensionPages)
        BaseFileWizard::applyExtensionPageShortTitle(m_d->wizardDialog, m_d->wizardDialog->addPage(p));

    return m_d->wizardDialog;
}

Core::GeneratedFiles QmlStandaloneAppWizard::generateFiles(const QWizard *w,
                                                           QString *errorMessage) const
{
    Q_UNUSED(errorMessage)

    const QmlStandaloneAppWizardDialog *wizard = qobject_cast<const QmlStandaloneAppWizardDialog*>(w);

    m_d->standaloneApp->setProjectName(wizard->projectName());
    m_d->standaloneApp->setProjectPath(wizard->path());
    m_d->standaloneApp->setSymbianTargetUid(wizard->m_qmlOptionsPage->symbianUid());
    m_d->standaloneApp->setSymbianSvgIcon(wizard->m_qmlOptionsPage->symbianSvgIcon());
    m_d->standaloneApp->setOrientation(wizard->m_qmlOptionsPage->orientation());
    m_d->standaloneApp->setNetworkEnabled(wizard->m_qmlOptionsPage->networkEnabled());
    if (m_d->type == QmlStandaloneAppWizard::ImportQmlFile)
        m_d->standaloneApp->setMainQmlFile(wizard->m_qmlSourcesPage->mainQmlFile());

    return m_d->standaloneApp->generateFiles(errorMessage);
}

bool QmlStandaloneAppWizard::postGenerateFiles(const QWizard *wizard, const Core::GeneratedFiles &l, QString *errorMessage)
{
    Q_UNUSED(wizard)
    const bool success = ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage);
    if (success && m_d->type == QmlStandaloneAppWizard::ImportQmlFile) {
        ProjectExplorer::ProjectExplorerPlugin::instance()->setCurrentFile(0, m_d->standaloneApp->mainQmlFile());
        Core::EditorManager::instance()->openEditor(m_d->standaloneApp->mainQmlFile());
    }
    return success;
}

void QmlStandaloneAppWizard::useProjectPath(const QString &projectName, const QString &projectPath)
{
    m_d->wizardDialog->m_qmlOptionsPage->setSymbianUid(QmlStandaloneApp::symbianUidForPath(projectPath + projectName));
}

} // namespace Internal
} // namespace QmlProjectManager

#include "qmlstandaloneappwizard.moc"
<commit_msg>Typo fix.<commit_after>/**************************************************************************
**
** This file is part of Qt Creator
**
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
**
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** Commercial Usage
**
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
**
** 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.
**
** If you are unsure which license is appropriate for your use, please
** contact the sales department at http://qt.nokia.com/contact.
**
**************************************************************************/

#include "qmlstandaloneappwizard.h"
#include "qmlstandaloneappwizardpages.h"
#include "qmlstandaloneapp.h"

#include "qmlprojectconstants.h"

#include <projectexplorer/baseprojectwizarddialog.h>
#include <projectexplorer/customwizard/customwizard.h>
#include <projectexplorer/projectexplorer.h>
#include <coreplugin/editormanager/editormanager.h>

#include <QtGui/QIcon>

#include <QtGui/QPainter>
#include <QtGui/QPixmap>

#include <QtCore/QTextStream>
#include <QtCore/QCoreApplication>
#include <QtCore/QDir>
#include <QtCore/QFile>

namespace QmlProjectManager {
namespace Internal {

class QmlStandaloneAppWizardDialog : public ProjectExplorer::BaseProjectWizardDialog
{
    Q_OBJECT

public:
    explicit QmlStandaloneAppWizardDialog(QmlStandaloneAppWizard::WizardType type, QWidget *parent = 0);

private:
    QmlStandaloneAppWizard::WizardType m_type;
    class QmlStandaloneAppWizardSourcesPage *m_qmlSourcesPage;
    class QmlStandaloneAppWizardOptionsPage *m_qmlOptionsPage;
    friend class QmlStandaloneAppWizard;
};

QmlStandaloneAppWizardDialog::QmlStandaloneAppWizardDialog(QmlStandaloneAppWizard::WizardType type,
                                                           QWidget *parent)
    : ProjectExplorer::BaseProjectWizardDialog(parent)
    , m_type(type)
{
    setWindowTitle(m_type == QmlStandaloneAppWizard::NewQmlFile
                       ? tr("New Standalone QML Project")
                       : tr("Standalone QML Project from existing QML Project"));
    setIntroDescription(m_type == QmlStandaloneAppWizard::NewQmlFile
                       ? tr("This wizard generates a Standalone QML application project.")
                       : tr("This wizard imports an existing QML application and creates a standalone version of it."));

    m_qmlSourcesPage = new QmlStandaloneAppWizardSourcesPage;
    m_qmlSourcesPage->setMainQmlFileChooserVisible(m_type == QmlStandaloneAppWizard::ImportQmlFile);
    if (m_type == QmlStandaloneAppWizard::ImportQmlFile) {
        const int qmlSourcesPagePageId = addPage(m_qmlSourcesPage);
        wizardProgress()->item(qmlSourcesPagePageId)->setTitle(tr("Qml Sources"));
    }

    m_qmlOptionsPage = new QmlStandaloneAppWizardOptionsPage;
    const int qmlOptionsPagePageId = addPage(m_qmlOptionsPage);
    wizardProgress()->item(qmlOptionsPagePageId)->setTitle(tr("Qml App options"));
}

class QmlStandaloneAppWizardPrivate
{
    QmlStandaloneAppWizard::WizardType type;
    class QmlStandaloneApp *standaloneApp;
    class QmlStandaloneAppWizardDialog *wizardDialog;
    friend class QmlStandaloneAppWizard;
};

QmlStandaloneAppWizard::QmlStandaloneAppWizard(WizardType type)
    : Core::BaseFileWizard(parameters(type))
    , m_d(new QmlStandaloneAppWizardPrivate)
{
    m_d->type = type;
    m_d->standaloneApp = new QmlStandaloneApp;
    m_d->wizardDialog = 0;
}

QmlStandaloneAppWizard::~QmlStandaloneAppWizard()
{
    delete m_d->standaloneApp;
}

Core::BaseFileWizardParameters QmlStandaloneAppWizard::parameters(WizardType type)
{
    Core::BaseFileWizardParameters parameters(ProjectWizard);
    parameters.setIcon(QIcon(QLatin1String(Constants::QML_WIZARD_ICON)));
    parameters.setDisplayName(type == QmlStandaloneAppWizard::NewQmlFile
                              ? tr("Qt QML New Standalone Application")
                              : tr("Qt QML Imported Standalone Application"));
    parameters.setId(QLatin1String(type == QmlStandaloneAppWizard::NewQmlFile
                                   ? "QA.QML New Standalone Application"
                                   : "QA.QML Imported Standalone Application"));
    parameters.setDescription(type == QmlStandaloneAppWizard::NewQmlFile
                              ? tr("Creates a standalone, mobile-deployable Qt QML application "
                                   "project. A lightweight Qt/C++ application with a QDeclarativeView "
                                   "and a single QML file will be created.")
                              : tr("Creates a standalone, mobile-deployable Qt QML application "
                                   "project. An existing QML project will be imported and a lightweight "
                                   "Qt/C++ application with a QDeclarativeView will be created for it."));
    parameters.setCategory(QLatin1String(Constants::QML_WIZARD_CATEGORY));
    parameters.setDisplayCategory(QCoreApplication::translate(Constants::QML_WIZARD_TR_SCOPE,
                                                              Constants::QML_WIZARD_TR_CATEGORY));
    return parameters;
}

QWizard *QmlStandaloneAppWizard::createWizardDialog(QWidget *parent,
                                                    const QString &defaultPath,
                                                    const WizardPageList &extensionPages) const
{
    m_d->wizardDialog = new QmlStandaloneAppWizardDialog(m_d->type, parent);

    m_d->wizardDialog->setPath(defaultPath);
    m_d->wizardDialog->setProjectName(QmlStandaloneAppWizardDialog::uniqueProjectName(defaultPath));
    m_d->wizardDialog->m_qmlOptionsPage->setSymbianSvgIcon(m_d->standaloneApp->symbianSvgIcon());
    m_d->wizardDialog->m_qmlOptionsPage->setOrientation(m_d->standaloneApp->orientation());
    m_d->wizardDialog->m_qmlOptionsPage->setNetworkEnabled(m_d->standaloneApp->networkEnabled());
    m_d->wizardDialog->m_qmlOptionsPage->setLoadDummyData(m_d->standaloneApp->loadDummyData());
    connect(m_d->wizardDialog, SIGNAL(introPageLeft(QString, QString)), SLOT(useProjectPath(QString, QString)));

    foreach (QWizardPage *p, extensionPages)
        BaseFileWizard::applyExtensionPageShortTitle(m_d->wizardDialog, m_d->wizardDialog->addPage(p));

    return m_d->wizardDialog;
}

Core::GeneratedFiles QmlStandaloneAppWizard::generateFiles(const QWizard *w,
                                                           QString *errorMessage) const
{
    Q_UNUSED(errorMessage)

    const QmlStandaloneAppWizardDialog *wizard = qobject_cast<const QmlStandaloneAppWizardDialog*>(w);

    m_d->standaloneApp->setProjectName(wizard->projectName());
    m_d->standaloneApp->setProjectPath(wizard->path());
    m_d->standaloneApp->setSymbianTargetUid(wizard->m_qmlOptionsPage->symbianUid());
    m_d->standaloneApp->setSymbianSvgIcon(wizard->m_qmlOptionsPage->symbianSvgIcon());
    m_d->standaloneApp->setOrientation(wizard->m_qmlOptionsPage->orientation());
    m_d->standaloneApp->setNetworkEnabled(wizard->m_qmlOptionsPage->networkEnabled());
    if (m_d->type == QmlStandaloneAppWizard::ImportQmlFile)
        m_d->standaloneApp->setMainQmlFile(wizard->m_qmlSourcesPage->mainQmlFile());

    return m_d->standaloneApp->generateFiles(errorMessage);
}

bool QmlStandaloneAppWizard::postGenerateFiles(const QWizard *wizard, const Core::GeneratedFiles &l, QString *errorMessage)
{
    Q_UNUSED(wizard)
    const bool success = ProjectExplorer::CustomProjectWizard::postGenerateOpen(l, errorMessage);
    if (success && m_d->type == QmlStandaloneAppWizard::ImportQmlFile) {
        ProjectExplorer::ProjectExplorerPlugin::instance()->setCurrentFile(0, m_d->standaloneApp->mainQmlFile());
        Core::EditorManager::instance()->openEditor(m_d->standaloneApp->mainQmlFile());
    }
    return success;
}

void QmlStandaloneAppWizard::useProjectPath(const QString &projectName, const QString &projectPath)
{
    m_d->wizardDialog->m_qmlOptionsPage->setSymbianUid(QmlStandaloneApp::symbianUidForPath(projectPath + projectName));
}

} // namespace Internal
} // namespace QmlProjectManager

#include "qmlstandaloneappwizard.moc"
<|endoftext|>


<commit_before>//
// Created by dotdi on 16.11.16.
//

#include <histedit.h>
#include "InteractiveShell.h"
#include "helpers.h"
#include "Config.h"

namespace CSAOpt {
    static char *prompt(EditLine *el __attribute__((__unused__))) {
        static char a[] = ">> ";

        return a;
    }

    InteractiveShell::InteractiveShell(CSAOpt::CSAOptManager &_manager) : manager(_manager) {

    };

    void InteractiveShell::enter() {

        /* This holds all the state for our line editor */
        EditLine *el;

        /* This holds the info for our history */
        History *hist;

        /* Temp variables */
        int count;
        const char *line;
        HistEvent ev;

        /* Initialize the EditLine state to use our prompt function and
        emacs style editing. */

        el = el_init("csaopt", stdin, stdout, stderr);
        el_set(el, EL_PROMPT, &prompt);
        el_set(el, EL_EDITOR, "emacs");

        /* Initialize the history */
        hist = history_init();
        if (hist == 0) {
            fprintf(stderr, "history could not be initialized\n");
            return;
        }

        /* Set the size of the history */
        history(hist, &ev, H_SETSIZE, 800);
        history(hist, &ev, H_LOAD, Config::getInteractiveHistoryPath());

        /* This sets up the call back functions for history functionality */
        el_set(el, EL_HIST, history, hist);

        while (!this->aborted) {
            /* count is the number of characters read.
               line is a const char* of our command line with the tailing \n */
            line = el_gets(el, &count);

            /* In order to use our history we have to explicitly add commands
            to the history */
            if (count > 0) {
                history(hist, &ev, H_ENTER, line);

                std::vector<std::string> args;

                std::string token;
                std::istringstream ss(trim(line));

                while (std::getline(ss, token, ' ')) {
                    args.push_back(trim(token));
                }

                this->manager.handleInteractiveCommand(args[0], args);
            }
        }

        history(hist, &ev, H_SAVE, Config::getInteractiveHistoryPath());

        /* Clean up our memory */
        history_end(hist);
        el_end(el);
    }

    void InteractiveShell::abort() {
        this->aborted = true;
    }
}<commit_msg>made history file configurable<commit_after>//
// Created by dotdi on 16.11.16.
//

#include <histedit.h>
#include "InteractiveShell.h"
#include "helpers.h"
#include "Config.h"

namespace CSAOpt {
    static char *prompt(EditLine *el __attribute__((__unused__))) {
        static char a[] = ">> ";

        return a;
    }

    InteractiveShell::InteractiveShell(CSAOpt::CSAOptManager &_manager) : manager(_manager) {

    };

    void InteractiveShell::enter() {

        /* This holds all the state for our line editor */
        EditLine *el;

        /* This holds the info for our history */
        History *hist;

        /* Temp variables */
        int count;
        const char *line;
        HistEvent ev;

        /* Initialize the EditLine state to use our prompt function and
        emacs style editing. */

        el = el_init("csaopt", stdin, stdout, stderr);
        el_set(el, EL_PROMPT, &prompt);
        el_set(el, EL_EDITOR, "emacs");

        /* Initialize the history */
        hist = history_init();
        if (hist == 0) {
            fprintf(stderr, "history could not be initialized\n");
            return;
        }

        /* Set the size of the history */
        history(hist, &ev, H_SETSIZE, 800);
        history(hist, &ev, H_LOAD, Config::getInteractiveHistoryPath().c_str());

        /* This sets up the call back functions for history functionality */
        el_set(el, EL_HIST, history, hist);

        while (!this->aborted) {
            /* count is the number of characters read.
               line is a const char* of our command line with the tailing \n */
            line = el_gets(el, &count);

            /* In order to use our history we have to explicitly add commands
            to the history */
            if (count > 0) {
                history(hist, &ev, H_ENTER, line);

                std::vector<std::string> args;

                std::string token;
                std::istringstream ss(trim(line));

                while (std::getline(ss, token, ' ')) {
                    args.push_back(trim(token));
                }

                this->manager.handleInteractiveCommand(args[0], args);
            }
        }

        history(hist, &ev, H_SAVE, Config::getInteractiveHistoryPath().c_str());

        /* Clean up our memory */
        history_end(hist);
        el_end(el);
    }

    void InteractiveShell::abort() {
        this->aborted = true;
    }
}<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <cmath>
#include <numeric>
#include <vector>

#include "voice_engine/main/test/auto_test/fixtures/after_streaming_fixture.h"

#ifdef MAC_IPHONE
  const int kMinimumReasonableDelayEstimateMs = 30;
#else
  const int kMinimumReasonableDelayEstimateMs = 45;
#endif  // !MAC_IPHONE

class VideoSyncTest : public AfterStreamingFixture {
 protected:
  // This test will verify that delay estimates converge (e.g. the standard
  // deviation for the last five seconds' estimates is less than 20) without
  // manual observation. The test runs for 15 seconds, sampling once per second.
  // All samples are checked so they are greater than |min_estimate|.
  int CollectEstimatesDuring15Seconds(int min_estimate) {
    Sleep(1000);

    std::vector<int> all_delay_estimates;
    for (int second = 0; second < 15; second++) {
      int delay_estimate = 0;
      EXPECT_EQ(0, voe_vsync_->GetDelayEstimate(channel_, delay_estimate));

      EXPECT_GT(delay_estimate, min_estimate) <<
          "The delay estimate can not conceivably get lower than " <<
          min_estimate << " ms, it's unrealistic.";

      all_delay_estimates.push_back(delay_estimate);
      Sleep(1000);
    }

    return ComputeStandardDeviation(
        all_delay_estimates.begin() + 10, all_delay_estimates.end());
  }

  void CheckEstimatesConvergeReasonablyWell(int min_estimate) {
    float standard_deviation = CollectEstimatesDuring15Seconds(min_estimate);
    EXPECT_LT(standard_deviation, 20.0f);
  }

  // Computes the standard deviation by first estimating the sample variance
  // with an unbiased estimator.
  float ComputeStandardDeviation(std::vector<int>::const_iterator start,
                               std::vector<int>::const_iterator end) const {
    int num_elements = end - start;
    int mean = std::accumulate(start, end, 0) / num_elements;
    assert(num_elements > 1);

    float variance = 0;
    for (; start != end; ++start) {
      variance += (*start - mean) * (*start - mean) / (num_elements - 1);
    }
    return std::sqrt(variance);
  }
};

TEST_F(VideoSyncTest, CanGetPlayoutTimestampWhilePlayingWithoutSettingItFirst) {
  unsigned int ignored;
  EXPECT_EQ(0, voe_vsync_->GetPlayoutTimestamp(channel_, ignored));
}

TEST_F(VideoSyncTest, CannotSetInitTimestampWhilePlaying) {
  EXPECT_EQ(-1, voe_vsync_->SetInitTimestamp(channel_, 12345));
}

TEST_F(VideoSyncTest, CannotSetInitSequenceNumberWhilePlaying) {
  EXPECT_EQ(-1, voe_vsync_->SetInitSequenceNumber(channel_, 123));
}

TEST_F(VideoSyncTest, CanSetInitTimestampWhileStopped) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
}

TEST_F(VideoSyncTest, CanSetInitSequenceNumberWhileStopped) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
}

TEST_F(VideoSyncTest, DelayEstimatesStabilizeDuring15sAndAreNotTooLow) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
  EXPECT_EQ(0, voe_base_->StartSend(channel_));

  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
}

TEST_F(VideoSyncTest, DelayEstimatesStabilizeAfterNetEqMinDelayChanges45s) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
  EXPECT_EQ(0, voe_base_->StartSend(channel_));

  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
  EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 200));
  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
  EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 0));
  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
}

#if !defined(WEBRTC_ANDROID)
TEST_F(VideoSyncTest, CanGetPlayoutBufferSize) {
  int ignored;
  EXPECT_EQ(0, voe_vsync_->GetPlayoutBufferSize(ignored));
}
#endif  // !ANDROID
<commit_msg>Adjusted the deviation limit since the test seems to fail on the bot.<commit_after>/*
 *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include <cmath>
#include <numeric>
#include <vector>

#include "voice_engine/main/test/auto_test/fixtures/after_streaming_fixture.h"

#ifdef MAC_IPHONE
  const int kMinimumReasonableDelayEstimateMs = 30;
#else
  const int kMinimumReasonableDelayEstimateMs = 45;
#endif  // !MAC_IPHONE

class VideoSyncTest : public AfterStreamingFixture {
 protected:
  // This test will verify that delay estimates converge (e.g. the standard
  // deviation for the last five seconds' estimates is less than 20) without
  // manual observation. The test runs for 15 seconds, sampling once per second.
  // All samples are checked so they are greater than |min_estimate|.
  int CollectEstimatesDuring15Seconds(int min_estimate) {
    Sleep(1000);

    std::vector<int> all_delay_estimates;
    for (int second = 0; second < 15; second++) {
      int delay_estimate = 0;
      EXPECT_EQ(0, voe_vsync_->GetDelayEstimate(channel_, delay_estimate));

      EXPECT_GT(delay_estimate, min_estimate) <<
          "The delay estimate can not conceivably get lower than " <<
          min_estimate << " ms, it's unrealistic.";

      all_delay_estimates.push_back(delay_estimate);
      Sleep(1000);
    }

    return ComputeStandardDeviation(
        all_delay_estimates.begin() + 10, all_delay_estimates.end());
  }

  void CheckEstimatesConvergeReasonablyWell(int min_estimate) {
    float standard_deviation = CollectEstimatesDuring15Seconds(min_estimate);
    EXPECT_LT(standard_deviation, 30.0f);
  }

  // Computes the standard deviation by first estimating the sample variance
  // with an unbiased estimator.
  float ComputeStandardDeviation(std::vector<int>::const_iterator start,
                               std::vector<int>::const_iterator end) const {
    int num_elements = end - start;
    int mean = std::accumulate(start, end, 0) / num_elements;
    assert(num_elements > 1);

    float variance = 0;
    for (; start != end; ++start) {
      variance += (*start - mean) * (*start - mean) / (num_elements - 1);
    }
    return std::sqrt(variance);
  }
};

TEST_F(VideoSyncTest, CanGetPlayoutTimestampWhilePlayingWithoutSettingItFirst) {
  unsigned int ignored;
  EXPECT_EQ(0, voe_vsync_->GetPlayoutTimestamp(channel_, ignored));
}

TEST_F(VideoSyncTest, CannotSetInitTimestampWhilePlaying) {
  EXPECT_EQ(-1, voe_vsync_->SetInitTimestamp(channel_, 12345));
}

TEST_F(VideoSyncTest, CannotSetInitSequenceNumberWhilePlaying) {
  EXPECT_EQ(-1, voe_vsync_->SetInitSequenceNumber(channel_, 123));
}

TEST_F(VideoSyncTest, CanSetInitTimestampWhileStopped) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
}

TEST_F(VideoSyncTest, CanSetInitSequenceNumberWhileStopped) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
}

TEST_F(VideoSyncTest, DelayEstimatesStabilizeDuring15sAndAreNotTooLow) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
  EXPECT_EQ(0, voe_base_->StartSend(channel_));

  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
}

TEST_F(VideoSyncTest, DelayEstimatesStabilizeAfterNetEqMinDelayChanges45s) {
  EXPECT_EQ(0, voe_base_->StopSend(channel_));
  EXPECT_EQ(0, voe_vsync_->SetInitTimestamp(channel_, 12345));
  EXPECT_EQ(0, voe_vsync_->SetInitSequenceNumber(channel_, 123));
  EXPECT_EQ(0, voe_base_->StartSend(channel_));

  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
  EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 200));
  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
  EXPECT_EQ(0, voe_vsync_->SetMinimumPlayoutDelay(channel_, 0));
  CheckEstimatesConvergeReasonablyWell(kMinimumReasonableDelayEstimateMs);
}

#if !defined(WEBRTC_ANDROID)
TEST_F(VideoSyncTest, CanGetPlayoutBufferSize) {
  int ignored;
  EXPECT_EQ(0, voe_vsync_->GetPlayoutBufferSize(ignored));
}
#endif  // !ANDROID
<|endoftext|>


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

#include "llvm/ADT/StringMap.h"
#include "llvm/IR/User.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"

#include "PrevirtualizeInterfaces.h"

#include <vector>
#include <string>
#include <stdio.h>

using namespace llvm;

namespace previrt
{
  static inline GlobalValue::LinkageTypes
  localizeLinkage(GlobalValue::LinkageTypes l)
  {
    switch (l) {
    // TODO I'm not sure if all external definitions have an appropriate internal counterpart
    default:
      errs() << "Got other linkage! " << l << "\n";
      return l;
    case GlobalValue::ExternalLinkage:
      return GlobalValue::InternalLinkage;
    case GlobalValue::ExternalWeakLinkage:
      return GlobalValue::WeakODRLinkage;
    case GlobalValue::AppendingLinkage:
      return GlobalValue::AppendingLinkage;
    }
  }

  /*
   * Remove all code from the given module that is not necessary to
   * implement the given interface.
   */
  bool
  MinimizeComponent(Module& M, ComponentInterface& I)
  {
    bool modified = false;
    int hidden = 0;
    int internalized = 0;

    /*
    errs() << "<interface>\n";
    I.dump();
    errs() << "</interface>\n";
    */

    // Set all functions that are not in the interface to internal linkage only
    const StringMap<std::vector<CallInfo*> >::const_iterator end =
        I.calls.end();
    for (Module::iterator f = M.begin(), e = M.end(); f != e; ++f) {
      if (!f->isDeclaration() && f->hasExternalLinkage() &&
          I.calls.find(f->getName()) == end &&
          I.references.find(f->getName()) == I.references.end()) {
        errs() << "Hiding '" << f->getName() << "'\n";
        f->setLinkage(GlobalValue::InternalLinkage);
	hidden++;
        modified = true;
      }
    }

    // Set all initialized global variables that are not referenced in the interface to "localized linkage" only
    for (Module::global_iterator i = M.global_begin(), e = M.global_end(); i != e; ++i) {
      if (i->hasExternalLinkage() && i->hasInitializer() &&
          I.references.find(i->getName()) == I.references.end()) {
        errs() << "internalizing '" << i->getName() << "'\n";
        i->setLinkage(localizeLinkage(i->getLinkage()));
	internalized++;
        modified = true;
      }
    }
    /* TODO: We want to do this, but libc has some problems...
    for (Module::alias_iterator i = M.alias_begin(), e = M.alias_end(); i != e; ++i) {
      if (i->hasExternalLinkage() &&
          I.references.find(i->getName()) == I.references.end() &&
          I.calls.find(i->getName()) == end) {
        errs() << "internalizing '" << i->getName() << "'\n";
        i->setLinkage(localizeLinkage(i->getLinkage()));
        modified = true;
      }
    }
    */

    // Perform global dead code elimination
    // TODO: To what extent should we do this here, versus
    //       doing it elsewhere?
    PassManager<Module> cdeMgr;
    PassManager<Module>  mcMgr;
    cdeMgr.addPass(createGlobalDCEPass());
    //mfMgr.add(createMergeFunctionsPass());
    mcMgr.addPass(createConstantMergePass());
    bool moreToDo = true;
    unsigned int iters = 0;
    while (moreToDo && iters < 10000) {
      moreToDo = false;
      PreservedAnalyses cdePA = cdeMgr.run(M);
      if (cdePA.preserve<GlobalDCEPass>())
	moreToDo =true;
      //if (cdeMgr.run(M)) moreToDo = true;
      // (originally commented) if (mfMgr.run(M)) moreToDo = true;
      PreservedAnalyses mcPA = mcMgr.run(M);
      if (mcPA.preserve<ConstantMergePass>())
	moreTodo = true;
      //if (mcMgr.run(M)) moreToDo = true;
      modified = modified || moreToDo;
      ++iters;
    }

    if (moreToDo) {
      PreservedAnalyses cdePA = cdeMgr.run(M);
      if (cdePA.preserve<GlobalDCEPass>())
	errs() << "GlobalDCE still had more to do\n";

      //if (mfMgr.run(M)) errs() << "MergeFunctions still had more to do\n";

      PreserveAnalyses mcPA = mcMgr.run(M);
      if (mcPA.preserve<ConstantMergePass>())
	errs() << "MergeConstants still had more to do\n";
    }

    if (modified) {
      errs() << "Progress: hidden = " << hidden << " internalized " << internalized << "\n";
    }

    return modified;
  }

  static cl::list<std::string> OccamComponentInput(
      "Poccam-input", cl::NotHidden, cl::desc(
          "specifies the interface to prune with respect to"));
  class OccamPass : public ModulePass
  {
  public:
    ComponentInterface interface;
    static char ID;
  public:
    OccamPass() :
      ModulePass(ID)
    {

      errs() << "OccamPass()\n";

      for (cl::list<std::string>::const_iterator b =
          OccamComponentInput.begin(), e = OccamComponentInput.end(); b
          != e; ++b) {
        errs() << "Reading file '" << *b << "'...";
        if (interface.readFromFile(*b)) {
          errs() << "success\n";
        } else {
          errs() << "failed\n";
        }
      }
      errs() << "Done reading.\n";
    }
    virtual
    ~OccamPass()
    {
    }
  public:
    virtual bool
    runOnModule(Module& M)
    {
      errs() << "OccamPass::runOnModule: " << M.getModuleIdentifier() << "\n";
      return MinimizeComponent(M, this->interface);
    }
  };
  char OccamPass::ID;

  static RegisterPass<OccamPass> X("Poccam",
      "hide/eliminate all non-external dependencies", false, false);

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

#include "llvm/ADT/StringMap.h"
#include "llvm/IR/User.h"
#include "llvm/IR/InstVisitor.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Transforms/IPO.h"
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
#include "llvm/Pass.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/raw_ostream.h"

#include "PrevirtualizeInterfaces.h"

#include <vector>
#include <string>
#include <stdio.h>

using namespace llvm;

namespace previrt
{
  static inline GlobalValue::LinkageTypes
  localizeLinkage(GlobalValue::LinkageTypes l)
  {
    switch (l) {
    // TODO I'm not sure if all external definitions have an appropriate internal counterpart
    default:
      errs() << "Got other linkage! " << l << "\n";
      return l;
    case GlobalValue::ExternalLinkage:
      return GlobalValue::InternalLinkage;
    case GlobalValue::ExternalWeakLinkage:
      return GlobalValue::WeakODRLinkage;
    case GlobalValue::AppendingLinkage:
      return GlobalValue::AppendingLinkage;
    }
  }

  /*
   * Remove all code from the given module that is not necessary to
   * implement the given interface.
   */
  bool
  MinimizeComponent(Module& M, ComponentInterface& I)
  {
    bool modified = false;
    int hidden = 0;
    int internalized = 0;

    /*
    errs() << "<interface>\n";
    I.dump();
    errs() << "</interface>\n";
    */

    // Set all functions that are not in the interface to internal linkage only
    const StringMap<std::vector<CallInfo*> >::const_iterator end =
        I.calls.end();
    for (Module::iterator f = M.begin(), e = M.end(); f != e; ++f) {
      if (!f->isDeclaration() && f->hasExternalLinkage() &&
          I.calls.find(f->getName()) == end &&
          I.references.find(f->getName()) == I.references.end()) {
        errs() << "Hiding '" << f->getName() << "'\n";
        f->setLinkage(GlobalValue::InternalLinkage);
	hidden++;
        modified = true;
      }
    }

    // Set all initialized global variables that are not referenced in the interface to "localized linkage" only
    for (Module::global_iterator i = M.global_begin(), e = M.global_end(); i != e; ++i) {
      if (i->hasExternalLinkage() && i->hasInitializer() &&
          I.references.find(i->getName()) == I.references.end()) {
        errs() << "internalizing '" << i->getName() << "'\n";
        i->setLinkage(localizeLinkage(i->getLinkage()));
	internalized++;
        modified = true;
      }
    }
    /* TODO: We want to do this, but libc has some problems...
    for (Module::alias_iterator i = M.alias_begin(), e = M.alias_end(); i != e; ++i) {
      if (i->hasExternalLinkage() &&
          I.references.find(i->getName()) == I.references.end() &&
          I.calls.find(i->getName()) == end) {
        errs() << "internalizing '" << i->getName() << "'\n";
        i->setLinkage(localizeLinkage(i->getLinkage()));
        modified = true;
      }
    }
    */

    // Perform global dead code elimination
    // TODO: To what extent should we do this here, versus
    //       doing it elsewhere?
    PassManager<Module> cdeMgr;
    PassManager<Module>  mcMgr;
    cdeMgr.addPass(createGlobalDCEPass());
    //mfMgr.add(createMergeFunctionsPass());
    mcMgr.addPass(createConstantMergePass());
    bool moreToDo = true;
    unsigned int iters = 0;
    while (moreToDo && iters < 10000) {
      moreToDo = false;
      PreservedAnalyses cdePA = cdeMgr.run(M);
      if (cdePA.preserve<GlobalDCE>())
	moreToDo =true;
      //if (cdeMgr.run(M)) moreToDo = true;
      // (originally commented) if (mfMgr.run(M)) moreToDo = true;
      PreservedAnalyses mcPA = mcMgr.run(M);
      if (mcPA.preserve<ConstantMerge>())
	moreToDo = true;
      //if (mcMgr.run(M)) moreToDo = true;
      modified = modified || moreToDo;
      ++iters;
    }

    if (moreToDo) {
      PreservedAnalyses cdePA = cdeMgr.run(M);
      if (cdePA.preserve<GlobalDCE>())
	errs() << "GlobalDCE still had more to do\n";

      //if (mfMgr.run(M)) errs() << "MergeFunctions still had more to do\n";

      PreserveAnalyses mcPA = mcMgr.run(M);
      if (mcPA.preserve<ConstantMerge>())
	errs() << "MergeConstants still had more to do\n";
    }

    if (modified) {
      errs() << "Progress: hidden = " << hidden << " internalized " << internalized << "\n";
    }

    return modified;
  }

  static cl::list<std::string> OccamComponentInput(
      "Poccam-input", cl::NotHidden, cl::desc(
          "specifies the interface to prune with respect to"));
  class OccamPass : public ModulePass
  {
  public:
    ComponentInterface interface;
    static char ID;
  public:
    OccamPass() :
      ModulePass(ID)
    {

      errs() << "OccamPass()\n";

      for (cl::list<std::string>::const_iterator b =
          OccamComponentInput.begin(), e = OccamComponentInput.end(); b
          != e; ++b) {
        errs() << "Reading file '" << *b << "'...";
        if (interface.readFromFile(*b)) {
          errs() << "success\n";
        } else {
          errs() << "failed\n";
        }
      }
      errs() << "Done reading.\n";
    }
    virtual
    ~OccamPass()
    {
    }
  public:
    virtual bool
    runOnModule(Module& M)
    {
      errs() << "OccamPass::runOnModule: " << M.getModuleIdentifier() << "\n";
      return MinimizeComponent(M, this->interface);
    }
  };
  char OccamPass::ID;

  static RegisterPass<OccamPass> X("Poccam",
      "hide/eliminate all non-external dependencies", false, false);

}
<|endoftext|>


<commit_before>#include "common/viditem/vscviditemcam.h"

VSCVidItemCam::VSCVidItemCam(QTreeWidgetItem *parent)
: VSCVidItemInf(parent)
{

}
VSCVidItemCam::~VSCVidItemCam()
{

}<commit_msg>add filter support<commit_after>#include "common/viditem/vscviditemcam.h"

VSCVidItemCam::VSCVidItemCam(VidCamera cCam, ClientFactory &pFactory, QTreeWidgetItem *parent)
: m_cCam(cCam), VSCVidItemInf(pFactory, parent)
{
	QIcon icon1;
	icon1.addFile(QStringLiteral(":/device/resources/camera.png"), QSize(), QIcon::Normal, QIcon::Off);

	setIcon(0, icon1);

	setText(0, QApplication::translate(" ", m_cCam.strname().c_str(), 0));
	//setHidden(true);
}
VSCVidItemCam::~VSCVidItemCam()
{

}

void VSCVidItemCam::VidFilter(astring strFilter)
{
	if (strFilter.size() == 0)
	{
		setHidden(false);
		return;
	}
	std::size_t found = m_cCam.strname().find(strFilter);
	if (found != std::string::npos)
	{
		setHidden(false);
	}else
	{
		setHidden(true);
	}
}
<|endoftext|>


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

#include "geojson_datasource.hpp"
#include "geojson_featureset.hpp"

#include <fstream>
#include <algorithm>

// boost
#include <boost/variant.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>

#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/extensions/index/rtree/rtree.hpp>

// mapnik
#include <mapnik/unicode.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/json/feature_collection_parser.hpp>

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(geojson_datasource)

struct attr_value_converter : public boost::static_visitor<mapnik::eAttributeType>
{
    mapnik::eAttributeType operator() (mapnik::value_integer /*val*/) const
    {
        return mapnik::Integer;
    }

    mapnik::eAttributeType operator() (double /*val*/) const
    {
        return mapnik::Double;
    }

    mapnik::eAttributeType operator() (float /*val*/) const
    {
        return mapnik::Double;
    }

    mapnik::eAttributeType operator() (bool /*val*/) const
    {
        return mapnik::Boolean;
    }

    mapnik::eAttributeType operator() (std::string const& /*val*/) const
    {
        return mapnik::String;
    }

    mapnik::eAttributeType operator() (mapnik::value_unicode_string const& /*val*/) const
    {
        return mapnik::String;
    }

    mapnik::eAttributeType operator() (mapnik::value_null const& /*val*/) const
    {
        return mapnik::String;
    }
};

geojson_datasource::geojson_datasource(parameters const& params)
: datasource(params),
    type_(datasource::Vector),
    desc_(*params.get<std::string>("type"),
          *params.get<std::string>("encoding","utf-8")),
    file_(*params.get<std::string>("file","")),
    extent_(),
    tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
    features_(),
    tree_(16,1)
{
    if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");

    boost::optional<std::string> base = params.get<std::string>("base");
    if (base)
    {
        file_ = *base + "/" + file_;
    }

    typedef std::istreambuf_iterator<char> base_iterator_type;

#if defined (_WINDOWS)
    std::ifstream is(mapnik::utf8_to_utf16(file_),std::ios_base::in | std::ios_base::binary);
#else
    std::ifstream is(file_.c_str(),std::ios_base::in | std::ios_base::binary);
#endif
    if (!is.is_open())
    {
        throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + file_ + "'");
    }

    boost::spirit::multi_pass<base_iterator_type> begin =
        boost::spirit::make_default_multi_pass(base_iterator_type(is));

    boost::spirit::multi_pass<base_iterator_type> end =
        boost::spirit::make_default_multi_pass(base_iterator_type());

    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
    mapnik::json::feature_collection_parser<boost::spirit::multi_pass<base_iterator_type> > p(ctx,*tr_);
    bool result = p.parse(begin,end, features_);
    if (!result)
    {
        throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");
    }

    bool first = true;
    std::size_t count=0;
    for (mapnik::feature_ptr f : features_)
    {
        mapnik::box2d<double> const& box = f->envelope();
        if (first)
        {
            extent_ = box;
            first = false;
            mapnik::feature_kv_iterator f_itr = f->begin();
            mapnik::feature_kv_iterator f_end = f->end();
            for ( ;f_itr!=f_end; ++f_itr)
            {
                desc_.add_descriptor(mapnik::attribute_descriptor(boost::get<0>(*f_itr),
                    boost::apply_visitor(attr_value_converter(),boost::get<1>(*f_itr).base())));
            }
        }
        else
        {
            extent_.expand_to_include(box);
        }
        tree_.insert(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())), count++);
    }
}

geojson_datasource::~geojson_datasource() { }

const char * geojson_datasource::name()
{
    return "geojson";
}

boost::optional<mapnik::datasource::geometry_t> geojson_datasource::get_geometry_type() const
{
    boost::optional<mapnik::datasource::geometry_t> result;
    int multi_type = 0;
    unsigned num_features = features_.size();
    for (unsigned i = 0; i < num_features && i < 5; ++i)
    {
        mapnik::util::to_ds_type(features_[i]->paths(),result);
        if (result)
        {
            int type = static_cast<int>(*result);
            if (multi_type > 0 && multi_type != type)
            {
                result.reset(mapnik::datasource::Collection);
                return result;
            }
            multi_type = type;
        }
    }
    return result;
}

mapnik::datasource::datasource_t geojson_datasource::type() const
{
    return type_;
}

mapnik::box2d<double> geojson_datasource::envelope() const
{
    return extent_;
}

mapnik::layer_descriptor geojson_datasource::get_descriptor() const
{
    return desc_;
}

mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) const
{
    // if the query box intersects our world extent then query for features
    mapnik::box2d<double> const& b = q.get_bbox();
    if (extent_.intersects(b))
    {
        box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy()));
        index_array_ = tree_.find(box);
        return std::make_shared<geojson_featureset>(features_, index_array_.begin(), index_array_.end());
    }
    // otherwise return an empty featureset pointer
    return mapnik::featureset_ptr();
}

mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
{
    mapnik::box2d<double> query_bbox(pt, pt);
    query_bbox.pad(tol);
    mapnik::query q(query_bbox);
    std::vector<mapnik::attribute_descriptor> const& desc = desc_.get_descriptors();
    std::vector<mapnik::attribute_descriptor>::const_iterator itr = desc.begin();
    std::vector<mapnik::attribute_descriptor>::const_iterator end = desc.end();
    for ( ;itr!=end;++itr)
    {
        q.add_property_name(itr->get_name());
    }
    return features(q);
}
<commit_msg>+ avoid copying feature_ptr during r-tree initialisation<commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2012 Artem Pavlenko
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 *
 *****************************************************************************/

#include "geojson_datasource.hpp"
#include "geojson_featureset.hpp"

#include <fstream>
#include <algorithm>

// boost
#include <boost/variant.hpp>
#include <boost/make_shared.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/spirit/include/support_multi_pass.hpp>

#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/geometries/geometries.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/extensions/index/rtree/rtree.hpp>

// mapnik
#include <mapnik/unicode.hpp>
#include <mapnik/utils.hpp>
#include <mapnik/feature.hpp>
#include <mapnik/feature_kv_iterator.hpp>
#include <mapnik/value_types.hpp>
#include <mapnik/box2d.hpp>
#include <mapnik/debug.hpp>
#include <mapnik/proj_transform.hpp>
#include <mapnik/projection.hpp>
#include <mapnik/util/geometry_to_ds_type.hpp>
#include <mapnik/json/feature_collection_parser.hpp>

using mapnik::datasource;
using mapnik::parameters;

DATASOURCE_PLUGIN(geojson_datasource)

struct attr_value_converter : public boost::static_visitor<mapnik::eAttributeType>
{
    mapnik::eAttributeType operator() (mapnik::value_integer /*val*/) const
    {
        return mapnik::Integer;
    }

    mapnik::eAttributeType operator() (double /*val*/) const
    {
        return mapnik::Double;
    }

    mapnik::eAttributeType operator() (float /*val*/) const
    {
        return mapnik::Double;
    }

    mapnik::eAttributeType operator() (bool /*val*/) const
    {
        return mapnik::Boolean;
    }

    mapnik::eAttributeType operator() (std::string const& /*val*/) const
    {
        return mapnik::String;
    }

    mapnik::eAttributeType operator() (mapnik::value_unicode_string const& /*val*/) const
    {
        return mapnik::String;
    }

    mapnik::eAttributeType operator() (mapnik::value_null const& /*val*/) const
    {
        return mapnik::String;
    }
};

geojson_datasource::geojson_datasource(parameters const& params)
: datasource(params),
    type_(datasource::Vector),
    desc_(*params.get<std::string>("type"),
          *params.get<std::string>("encoding","utf-8")),
    file_(*params.get<std::string>("file","")),
    extent_(),
    tr_(new mapnik::transcoder(*params.get<std::string>("encoding","utf-8"))),
    features_(),
    tree_(16,1)
{
    if (file_.empty()) throw mapnik::datasource_exception("GeoJSON Plugin: missing <file> parameter");

    boost::optional<std::string> base = params.get<std::string>("base");
    if (base)
    {
        file_ = *base + "/" + file_;
    }

    typedef std::istreambuf_iterator<char> base_iterator_type;

#if defined (_WINDOWS)
    std::ifstream is(mapnik::utf8_to_utf16(file_),std::ios_base::in | std::ios_base::binary);
#else
    std::ifstream is(file_.c_str(),std::ios_base::in | std::ios_base::binary);
#endif
    if (!is.is_open())
    {
        throw mapnik::datasource_exception("GeoJSON Plugin: could not open: '" + file_ + "'");
    }

    boost::spirit::multi_pass<base_iterator_type> begin =
        boost::spirit::make_default_multi_pass(base_iterator_type(is));

    boost::spirit::multi_pass<base_iterator_type> end =
        boost::spirit::make_default_multi_pass(base_iterator_type());

    mapnik::context_ptr ctx = std::make_shared<mapnik::context_type>();
    mapnik::json::feature_collection_parser<boost::spirit::multi_pass<base_iterator_type> > p(ctx,*tr_);
    bool result = p.parse(begin,end, features_);
    if (!result)
    {
        throw mapnik::datasource_exception("geojson_datasource: Failed parse GeoJSON file '" + file_ + "'");
    }

    bool first = true;
    std::size_t count=0;
    for (mapnik::feature_ptr const& f : features_)
    {
        mapnik::box2d<double> const& box = f->envelope();
        if (first)
        {
            extent_ = box;
            first = false;
            mapnik::feature_kv_iterator f_itr = f->begin();
            mapnik::feature_kv_iterator f_end = f->end();
            for ( ;f_itr!=f_end; ++f_itr)
            {
                desc_.add_descriptor(mapnik::attribute_descriptor(boost::get<0>(*f_itr),
                    boost::apply_visitor(attr_value_converter(),boost::get<1>(*f_itr).base())));
            }
        }
        else
        {
            extent_.expand_to_include(box);
        }
        tree_.insert(box_type(point_type(box.minx(),box.miny()),point_type(box.maxx(),box.maxy())), count++);
    }
}

geojson_datasource::~geojson_datasource() { }

const char * geojson_datasource::name()
{
    return "geojson";
}

boost::optional<mapnik::datasource::geometry_t> geojson_datasource::get_geometry_type() const
{
    boost::optional<mapnik::datasource::geometry_t> result;
    int multi_type = 0;
    unsigned num_features = features_.size();
    for (unsigned i = 0; i < num_features && i < 5; ++i)
    {
        mapnik::util::to_ds_type(features_[i]->paths(),result);
        if (result)
        {
            int type = static_cast<int>(*result);
            if (multi_type > 0 && multi_type != type)
            {
                result.reset(mapnik::datasource::Collection);
                return result;
            }
            multi_type = type;
        }
    }
    return result;
}

mapnik::datasource::datasource_t geojson_datasource::type() const
{
    return type_;
}

mapnik::box2d<double> geojson_datasource::envelope() const
{
    return extent_;
}

mapnik::layer_descriptor geojson_datasource::get_descriptor() const
{
    return desc_;
}

mapnik::featureset_ptr geojson_datasource::features(mapnik::query const& q) const
{
    // if the query box intersects our world extent then query for features
    mapnik::box2d<double> const& b = q.get_bbox();
    if (extent_.intersects(b))
    {
        box_type box(point_type(b.minx(),b.miny()),point_type(b.maxx(),b.maxy()));
        index_array_ = tree_.find(box);
        return std::make_shared<geojson_featureset>(features_, index_array_.begin(), index_array_.end());
    }
    // otherwise return an empty featureset pointer
    return mapnik::featureset_ptr();
}

mapnik::featureset_ptr geojson_datasource::features_at_point(mapnik::coord2d const& pt, double tol) const
{
    mapnik::box2d<double> query_bbox(pt, pt);
    query_bbox.pad(tol);
    mapnik::query q(query_bbox);
    std::vector<mapnik::attribute_descriptor> const& desc = desc_.get_descriptors();
    std::vector<mapnik::attribute_descriptor>::const_iterator itr = desc.begin();
    std::vector<mapnik::attribute_descriptor>::const_iterator end = desc.end();
    for ( ;itr!=end;++itr)
    {
        q.add_property_name(itr->get_name());
    }
    return features(q);
}
<|endoftext|>


<commit_before>///
/// @file   PrimeGenerator.cpp
/// @brief  After a segment has been sieved PrimeGenerator is
///         used to reconstruct primes and prime k-tuplets from
///         1 bits of the sieve array.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/config.hpp>
#include <primesieve/littleendian_cast.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/SieveOfEratosthenes.hpp>
#include <primesieve/StorePrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <iostream>
#include <sstream>

using namespace std;

namespace primesieve {

/// popcount.cpp
uint64_t popcount(const uint64_t* array, uint64_t size);

const uint64_t PrimeGenerator::bitmasks_[6][5] =
{
  { END },
  { 0x06, 0x18, 0xc0, END },       // Twin primes:       b00000110, b00011000, b11000000
  { 0x07, 0x0e, 0x1c, 0x38, END }, // Prime triplets:    b00000111, b00001110, ...
  { 0x1e, END },                   // Prime quadruplets: b00011110
  { 0x1f, 0x3e, END },             // Prime quintuplets
  { 0x3f, END }                    // Prime sextuplets
};

PrimeGenerator::PrimeGenerator(PrimeSieve& ps, const PreSieve& preSieve) :
  SieveOfEratosthenes(max<uint64_t>(7, ps.getStart()),
                      ps.getStop(),
                      ps.getSieveSize(),
                      preSieve),
  ps_(ps),
  counts_(ps_.getCounts())
{
  if (ps_.isFlag(ps_.COUNT_TWINS, ps_.COUNT_SEXTUPLETS))
    init_kCounts();
}

/// Calculate the number of twins, triplets, ...
/// for each possible byte value
///
void PrimeGenerator::init_kCounts()
{
  for (uint_t i = 1; i < counts_.size(); i++)
  {
    if (ps_.isCount(i))
    {
      kCounts_[i].resize(256);

      for (uint64_t j = 0; j < 256; j++)
      {
        byte_t count = 0;
        for (const uint64_t* b = bitmasks_[i]; *b <= j; b++)
        {
          if ((j & *b) == *b)
            count++;
        }
        kCounts_[i][j] = count;
      }
    }
  }
}

/// Executed after each sieved segment.
/// @see sieveSegment() in SieveOfEratosthenes.cpp
///
void PrimeGenerator::generatePrimes(const byte_t* sieve, uint64_t sieveSize)
{
  if (ps_.isStore())
    storePrimes(ps_.getStore(), sieve, sieveSize);
  if (ps_.isCount())
    count(sieve, sieveSize);
  if (ps_.isPrint())
    print(sieve, sieveSize);
  if (ps_.isStatus())
    ps_.updateStatus(sieveSize * NUMBERS_PER_BYTE);
}

void PrimeGenerator::storePrimes(Store& store, const byte_t* sieve, uint64_t sieveSize) const
{
  uint64_t low = getSegmentLow();

  for (uint64_t i = 0; i < sieveSize; i += 8)
  {
    uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);
    while (bits)
      store(nextPrime(&bits, low));

    low += NUMBERS_PER_BYTE * 8;
  }
}

/// Count the primes and prime k-tuplets
/// in the current segment
///
void PrimeGenerator::count(const byte_t* sieve, uint64_t sieveSize)
{
  if (ps_.isFlag(ps_.COUNT_PRIMES))
    counts_[0] += popcount((const uint64_t*) sieve, ceilDiv(sieveSize, 8));

  // i = 1 twins, i = 2 triplets, ...
  for (uint_t i = 1; i < counts_.size(); i++)
  {
    if (ps_.isCount(i))
    {
      uint64_t sum = 0;

      for (uint64_t j = 0; j < sieveSize; j += 4)
      {
        sum += kCounts_[i][sieve[j+0]];
        sum += kCounts_[i][sieve[j+1]];
        sum += kCounts_[i][sieve[j+2]];
        sum += kCounts_[i][sieve[j+3]];
      }

      counts_[i] += sum;
    }
  }
}

/// Print primes and prime k-tuplets to cout.
/// primes <= 5 are handled in processSmallPrimes().
///
void PrimeGenerator::print(const byte_t* sieve, uint64_t sieveSize) const
{
  if (ps_.isFlag(ps_.PRINT_PRIMES))
  {
    uint64_t low = getSegmentLow();
    ostringstream primes;

    for (uint64_t i = 0; i < sieveSize; i += 8)
    {
      uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);
      while (bits)
        primes << nextPrime(&bits, low) << '\n';

      low += NUMBERS_PER_BYTE * 8;
    }

    cout << primes.str();
  }

  // print prime k-tuplets
  if (ps_.isFlag(ps_.PRINT_TWINS, ps_.PRINT_SEXTUPLETS))
  {
    uint_t i = 1; // i = 1 twins, i = 2 triplets, ...
    uint64_t low = getSegmentLow();
    ostringstream kTuplets;

    for (; !ps_.isPrint(i); i++);
    for (uint64_t j = 0; j < sieveSize; j++, low += NUMBERS_PER_BYTE)
    {
      for (const uint64_t* bitmask = bitmasks_[i]; *bitmask <= sieve[j]; bitmask++)
      {
        if ((sieve[j] & *bitmask) == *bitmask)
        {
          kTuplets << "(";
          uint64_t bits = *bitmask;
          while (bits != 0)
          {
            kTuplets << nextPrime(&bits, low);
            kTuplets << ((bits != 0) ? ", " : ")\n");
          }
        }
      }
    }

    cout << kTuplets.str();
  }
}

} // namespace
<commit_msg>Print primes faster<commit_after>///
/// @file   PrimeGenerator.cpp
/// @brief  After a segment has been sieved PrimeGenerator is
///         used to reconstruct primes and prime k-tuplets from
///         1 bits of the sieve array.
///
/// Copyright (C) 2018 Kim Walisch, <kim.walisch@gmail.com>
///
/// This file is distributed under the BSD License. See the COPYING
/// file in the top level directory.
///

#include <primesieve/config.hpp>
#include <primesieve/littleendian_cast.hpp>
#include <primesieve/pmath.hpp>
#include <primesieve/PrimeGenerator.hpp>
#include <primesieve/PrimeSieve.hpp>
#include <primesieve/SieveOfEratosthenes.hpp>
#include <primesieve/StorePrimes.hpp>

#include <stdint.h>
#include <algorithm>
#include <iostream>
#include <sstream>

using namespace std;

namespace primesieve {

/// popcount.cpp
uint64_t popcount(const uint64_t* array, uint64_t size);

const uint64_t PrimeGenerator::bitmasks_[6][5] =
{
  { END },
  { 0x06, 0x18, 0xc0, END },       // Twin primes:       b00000110, b00011000, b11000000
  { 0x07, 0x0e, 0x1c, 0x38, END }, // Prime triplets:    b00000111, b00001110, ...
  { 0x1e, END },                   // Prime quadruplets: b00011110
  { 0x1f, 0x3e, END },             // Prime quintuplets
  { 0x3f, END }                    // Prime sextuplets
};

PrimeGenerator::PrimeGenerator(PrimeSieve& ps, const PreSieve& preSieve) :
  SieveOfEratosthenes(max<uint64_t>(7, ps.getStart()),
                      ps.getStop(),
                      ps.getSieveSize(),
                      preSieve),
  ps_(ps),
  counts_(ps_.getCounts())
{
  if (ps_.isFlag(ps_.COUNT_TWINS, ps_.COUNT_SEXTUPLETS))
    init_kCounts();
}

/// Calculate the number of twins, triplets, ...
/// for each possible byte value
///
void PrimeGenerator::init_kCounts()
{
  for (uint_t i = 1; i < counts_.size(); i++)
  {
    if (ps_.isCount(i))
    {
      kCounts_[i].resize(256);

      for (uint64_t j = 0; j < 256; j++)
      {
        byte_t count = 0;
        for (const uint64_t* b = bitmasks_[i]; *b <= j; b++)
        {
          if ((j & *b) == *b)
            count++;
        }
        kCounts_[i][j] = count;
      }
    }
  }
}

/// Executed after each sieved segment.
/// @see sieveSegment() in SieveOfEratosthenes.cpp
///
void PrimeGenerator::generatePrimes(const byte_t* sieve, uint64_t sieveSize)
{
  if (ps_.isStore())
    storePrimes(ps_.getStore(), sieve, sieveSize);
  if (ps_.isCount())
    count(sieve, sieveSize);
  if (ps_.isPrint())
    print(sieve, sieveSize);
  if (ps_.isStatus())
    ps_.updateStatus(sieveSize * NUMBERS_PER_BYTE);
}

void PrimeGenerator::storePrimes(Store& store, const byte_t* sieve, uint64_t sieveSize) const
{
  uint64_t low = getSegmentLow();

  for (uint64_t i = 0; i < sieveSize; i += 8)
  {
    uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);
    while (bits)
      store(nextPrime(&bits, low));

    low += NUMBERS_PER_BYTE * 8;
  }
}

/// Count the primes and prime k-tuplets
/// in the current segment
///
void PrimeGenerator::count(const byte_t* sieve, uint64_t sieveSize)
{
  if (ps_.isFlag(ps_.COUNT_PRIMES))
    counts_[0] += popcount((const uint64_t*) sieve, ceilDiv(sieveSize, 8));

  // i = 1 twins, i = 2 triplets, ...
  for (uint_t i = 1; i < counts_.size(); i++)
  {
    if (ps_.isCount(i))
    {
      uint64_t sum = 0;

      for (uint64_t j = 0; j < sieveSize; j += 4)
      {
        sum += kCounts_[i][sieve[j+0]];
        sum += kCounts_[i][sieve[j+1]];
        sum += kCounts_[i][sieve[j+2]];
        sum += kCounts_[i][sieve[j+3]];
      }

      counts_[i] += sum;
    }
  }
}

/// Print primes and prime k-tuplets to cout.
/// primes <= 5 are handled in processSmallPrimes().
///
void PrimeGenerator::print(const byte_t* sieve, uint64_t sieveSize) const
{
  if (ps_.isFlag(ps_.PRINT_PRIMES))
  {
    uint64_t i = 0;
    uint64_t low = getSegmentLow();

    while (i < sieveSize)
    {
      uint64_t size = min(i + (1 << 16), sieveSize);
      ostringstream primes;

      for (; i < size; i += 8)
      {
        uint64_t bits = littleendian_cast<uint64_t>(&sieve[i]);
        while (bits)
          primes << nextPrime(&bits, low) << '\n';

        low += NUMBERS_PER_BYTE * 8;
      }

      cout << primes.str();
    }
  }

  // print prime k-tuplets
  if (ps_.isFlag(ps_.PRINT_TWINS, ps_.PRINT_SEXTUPLETS))
  {
    uint_t i = 1; // i = 1 twins, i = 2 triplets, ...
    uint64_t low = getSegmentLow();
    ostringstream kTuplets;

    for (; !ps_.isPrint(i); i++);
    for (uint64_t j = 0; j < sieveSize; j++, low += NUMBERS_PER_BYTE)
    {
      for (const uint64_t* bitmask = bitmasks_[i]; *bitmask <= sieve[j]; bitmask++)
      {
        if ((sieve[j] & *bitmask) == *bitmask)
        {
          kTuplets << "(";
          uint64_t bits = *bitmask;
          while (bits != 0)
          {
            kTuplets << nextPrime(&bits, low);
            kTuplets << ((bits != 0) ? ", " : ")\n");
          }
        }
      }
    }

    cout << kTuplets.str();
  }
}

} // namespace
<|endoftext|>