<commit_before>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osg/PrimitiveSet>
#include <osg/BufferObject>
#include <osg/State>
#include <osg/Notify>

using namespace osg;

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// PrimitiveSet
//
unsigned int PrimitiveSet::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON): return (getNumIndices()>0) ? 1 : 0;
    }
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawArray
//
void DrawArrays::draw(State& state, bool) const
{
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
    GLenum mode = _mode;
    if (_mode==GL_QUADS)
    {
        state.drawQuads(_first, _count, _numInstances);
        return;
    }
    else if (mode==GL_POLYGON)
    {
        mode = GL_TRIANGLE_FAN;
    }
    else if (mode==GL_QUAD_STRIP)
    {
        mode = GL_TRIANGLE_STRIP;
    }

    if (_numInstances>=1) state.glDrawArraysInstanced(mode,_first,_count, _numInstances);
    else glDrawArrays(mode,_first,_count);
#else
    if (_numInstances>=1) state.glDrawArraysInstanced(_mode,_first,_count, _numInstances);
    else glDrawArrays(_mode,_first,_count);
#endif
}

void DrawArrays::accept(PrimitiveFunctor& functor) const
{
    functor.drawArrays(_mode,_first,_count);
}

void DrawArrays::accept(PrimitiveIndexFunctor& functor) const
{
    functor.drawArrays(_mode,_first,_count);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawArrayLengths
//
unsigned int DrawArrayLengths::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON): return size();
    }
    return 0;
}

void DrawArrayLengths::draw(State& state, bool) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (_mode==GL_QUADS)
        {
            GLint first = _first;
            for(vector_type::const_iterator itr=begin();
                itr!=end();
                ++itr)
            {
                state.drawQuads(first, *itr, _numInstances);
                first += *itr;
            }

            return;
        }
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        glDrawArrays(mode,first,*itr);
        first += *itr;
    }

}

void DrawArrayLengths::accept(PrimitiveFunctor& functor) const
{
    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        functor.drawArrays(_mode,first,*itr);
        first += *itr;
    }
}

void DrawArrayLengths::accept(PrimitiveIndexFunctor& functor) const
{
    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        functor.drawArrays(_mode,first,*itr);
        first += *itr;
    }
}

unsigned int DrawArrayLengths::getNumIndices() const
{
    unsigned int count = 0;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        count += *itr;
    }
    return count;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUByte
//
DrawElementsUByte::~DrawElementsUByte()
{
    releaseGLObjects();
}

void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
    }
}

void DrawElementsUByte::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUByte::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUByte::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUShort
//
DrawElementsUShort::~DrawElementsUShort()
{
    releaseGLObjects();
}

void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
    }
}

void DrawElementsUShort::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUShort::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUShort::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUInt
//
DrawElementsUInt::~DrawElementsUInt()
{
    releaseGLObjects();
}

void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
    }
}

void DrawElementsUInt::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUInt::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUInt::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MultiDrawArrays
//
#ifdef OSG_HAS_MULTIDRAWARRAYS
void MultiDrawArrays::draw(osg::State& state, bool) const
{
    // OSG_NOTICE<<"osg::MultiDrawArrays::draw"<<std::endl;

    GLExtensions* ext = state.get<GLExtensions>();
    if (ext->glMultiDrawArrays)
    {
        GLsizei primcount = std::min(_firsts.size(), _counts.size());

        ext->glMultiDrawArrays(_mode, &_firsts.front(), &_counts.front(), primcount);
    }
}

void MultiDrawArrays::accept(PrimitiveFunctor& functor) const
{
    unsigned int primcount = std::min(_firsts.size(), _counts.size());
    for(unsigned int i=0; i<primcount; ++i)
    {
        functor.drawArrays(_mode, _firsts[i], _counts[i]);
    }
}

void MultiDrawArrays::accept(PrimitiveIndexFunctor& functor) const
{
    unsigned int primcount = std::min(_firsts.size(), _counts.size());
    for(unsigned int i=0; i<primcount; ++i)
    {
        functor.drawArrays(_mode, _firsts[i], _counts[i]);
    }
}

unsigned int MultiDrawArrays::getNumIndices() const
{
    unsigned int total=0;
    for(Counts::const_iterator itr = _counts.begin(); itr!=_counts.end(); ++itr)
    {
        total += *itr;
    }
    return total;
}

unsigned int MultiDrawArrays::index(unsigned int pos) const
{
    unsigned int i;
    for(i=0; i<_counts.size(); ++i)
    {
        unsigned int count = _counts[i];
        if (pos<count) break;
        pos -= count;
    }
    if (i>=_firsts.size()) return 0;

    return _firsts[i] + pos;
}

void MultiDrawArrays::offsetIndices(int offset)
{
    for(Firsts::iterator itr = _firsts.begin(); itr!=_firsts.end(); ++itr)
    {
        *itr += offset;
    }
}

unsigned int MultiDrawArrays::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON):
        {
            unsigned int primcount = std::min(_firsts.size(), _counts.size());
            return primcount;
        }
    }
    return 0;
}

void MultiDrawArrays::add(GLint first, GLsizei count)
{
    _firsts.push_back(first);
    _counts.push_back(count);
}
#endif<commit_msg>Update PrimitiveSet.cpp<commit_after>/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield
 *
 * This library is open source and may be redistributed and/or modified under
 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
 * (at your option) any later version.  The full license is in LICENSE file
 * included with this distribution, and on the openscenegraph.org website.
 *
 * 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
 * OpenSceneGraph Public License for more details.
*/
#include <osg/PrimitiveSet>
#include <osg/BufferObject>
#include <osg/State>
#include <osg/Notify>
#include <algorithm>

using namespace osg;

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// PrimitiveSet
//
unsigned int PrimitiveSet::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON): return (getNumIndices()>0) ? 1 : 0;
    }
    return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawArray
//
void DrawArrays::draw(State& state, bool) const
{
#if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
    GLenum mode = _mode;
    if (_mode==GL_QUADS)
    {
        state.drawQuads(_first, _count, _numInstances);
        return;
    }
    else if (mode==GL_POLYGON)
    {
        mode = GL_TRIANGLE_FAN;
    }
    else if (mode==GL_QUAD_STRIP)
    {
        mode = GL_TRIANGLE_STRIP;
    }

    if (_numInstances>=1) state.glDrawArraysInstanced(mode,_first,_count, _numInstances);
    else glDrawArrays(mode,_first,_count);
#else
    if (_numInstances>=1) state.glDrawArraysInstanced(_mode,_first,_count, _numInstances);
    else glDrawArrays(_mode,_first,_count);
#endif
}

void DrawArrays::accept(PrimitiveFunctor& functor) const
{
    functor.drawArrays(_mode,_first,_count);
}

void DrawArrays::accept(PrimitiveIndexFunctor& functor) const
{
    functor.drawArrays(_mode,_first,_count);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawArrayLengths
//
unsigned int DrawArrayLengths::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON): return size();
    }
    return 0;
}

void DrawArrayLengths::draw(State& state, bool) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (_mode==GL_QUADS)
        {
            GLint first = _first;
            for(vector_type::const_iterator itr=begin();
                itr!=end();
                ++itr)
            {
                state.drawQuads(first, *itr, _numInstances);
                first += *itr;
            }

            return;
        }
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        glDrawArrays(mode,first,*itr);
        first += *itr;
    }

}

void DrawArrayLengths::accept(PrimitiveFunctor& functor) const
{
    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        functor.drawArrays(_mode,first,*itr);
        first += *itr;
    }
}

void DrawArrayLengths::accept(PrimitiveIndexFunctor& functor) const
{
    GLint first = _first;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        functor.drawArrays(_mode,first,*itr);
        first += *itr;
    }
}

unsigned int DrawArrayLengths::getNumIndices() const
{
    unsigned int count = 0;
    for(vector_type::const_iterator itr=begin();
        itr!=end();
        ++itr)
    {
        count += *itr;
    }
    return count;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUByte
//
DrawElementsUByte::~DrawElementsUByte()
{
    releaseGLObjects();
}

void DrawElementsUByte::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_BYTE, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_BYTE, &front());
    }
}

void DrawElementsUByte::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUByte::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUByte::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUShort
//
DrawElementsUShort::~DrawElementsUShort()
{
    releaseGLObjects();
}

void DrawElementsUShort::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_SHORT, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_SHORT, &front());
    }
}

void DrawElementsUShort::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUShort::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUShort::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// DrawElementsUInt
//
DrawElementsUInt::~DrawElementsUInt()
{
    releaseGLObjects();
}

void DrawElementsUInt::draw(State& state, bool useVertexBufferObjects) const
{
    GLenum mode = _mode;
    #if defined(OSG_GLES1_AVAILABLE) || defined(OSG_GLES2_AVAILABLE)
        if (mode==GL_POLYGON) mode = GL_TRIANGLE_FAN;
        if (mode==GL_QUAD_STRIP) mode = GL_TRIANGLE_STRIP;
    #endif

    if (useVertexBufferObjects)
    {
        GLBufferObject* ebo = getOrCreateGLBufferObject(state.getContextID());
        state.bindElementBufferObject(ebo);
        if (ebo)
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_INT, (const GLvoid *)(ebo->getOffset(getBufferIndex())));
        }
        else
        {
            if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
            else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
        }
    }
    else
    {
        if (_numInstances>=1) state.glDrawElementsInstanced(mode, size(), GL_UNSIGNED_INT, &front(), _numInstances);
        else glDrawElements(mode, size(), GL_UNSIGNED_INT, &front());
    }
}

void DrawElementsUInt::accept(PrimitiveFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUInt::accept(PrimitiveIndexFunctor& functor) const
{
    if (!empty()) functor.drawElements(_mode,size(),&front());
}

void DrawElementsUInt::offsetIndices(int offset)
{
    for(iterator itr=begin();
        itr!=end();
        ++itr)
    {
        *itr += offset;
    }
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// MultiDrawArrays
//
#ifdef OSG_HAS_MULTIDRAWARRAYS
void MultiDrawArrays::draw(osg::State& state, bool) const
{
    // OSG_NOTICE<<"osg::MultiDrawArrays::draw"<<std::endl;

    GLExtensions* ext = state.get<GLExtensions>();
    if (ext->glMultiDrawArrays)
    {
        GLsizei primcount = std::min(_firsts.size(), _counts.size());

        ext->glMultiDrawArrays(_mode, &_firsts.front(), &_counts.front(), primcount);
    }
}

void MultiDrawArrays::accept(PrimitiveFunctor& functor) const
{
    unsigned int primcount = std::min(_firsts.size(), _counts.size());
    for(unsigned int i=0; i<primcount; ++i)
    {
        functor.drawArrays(_mode, _firsts[i], _counts[i]);
    }
}

void MultiDrawArrays::accept(PrimitiveIndexFunctor& functor) const
{
    unsigned int primcount = std::min(_firsts.size(), _counts.size());
    for(unsigned int i=0; i<primcount; ++i)
    {
        functor.drawArrays(_mode, _firsts[i], _counts[i]);
    }
}

unsigned int MultiDrawArrays::getNumIndices() const
{
    unsigned int total=0;
    for(Counts::const_iterator itr = _counts.begin(); itr!=_counts.end(); ++itr)
    {
        total += *itr;
    }
    return total;
}

unsigned int MultiDrawArrays::index(unsigned int pos) const
{
    unsigned int i;
    for(i=0; i<_counts.size(); ++i)
    {
        unsigned int count = _counts[i];
        if (pos<count) break;
        pos -= count;
    }
    if (i>=_firsts.size()) return 0;

    return _firsts[i] + pos;
}

void MultiDrawArrays::offsetIndices(int offset)
{
    for(Firsts::iterator itr = _firsts.begin(); itr!=_firsts.end(); ++itr)
    {
        *itr += offset;
    }
}

unsigned int MultiDrawArrays::getNumPrimitives() const
{
    switch(_mode)
    {
        case(POINTS): return getNumIndices();
        case(LINES): return getNumIndices()/2;
        case(TRIANGLES): return getNumIndices()/3;
        case(QUADS): return getNumIndices()/4;
        case(LINE_STRIP):
        case(LINE_LOOP):
        case(TRIANGLE_STRIP):
        case(TRIANGLE_FAN):
        case(QUAD_STRIP):
        case(PATCHES):
        case(POLYGON):
        {
            unsigned int primcount = std::min(_firsts.size(), _counts.size());
            return primcount;
        }
    }
    return 0;
}

void MultiDrawArrays::add(GLint first, GLsizei count)
{
    _firsts.push_back(first);
    _counts.push_back(count);
}
#endif
<|endoftext|>


<commit_before>#include <string>
#include <iostream>
using namespace std;

#include "StudentTestScores.h"

int main(){
	cout << "CREATE new object x, name = Joe numTestScores = 4" << endl << endl;
	StudentTestScores x("joe", 4);
	cout << "READ standard input for values for test scores of joe, and rename joe" << endl << endl;
	cin >> x;
	cout << endl << "CREATE new object y with name = Chris and default numTestScores" << endl << endl;
	StudentTestScores y("Chris");
	cout << "OUTPUT object y via standard output operators" << endl << endl;
	cout << y;
	cout << endl << "ASSIGN to object y object x using assignment operator" << endl << endl;
	y=x;
	cout << "OUTPUT object x via display function." << endl << endl;
	x.Display();
	cout << endl << "ADD a test score of 79 to object x" << endl << endl;
	x.addTestScore(79);
	cout << "OUTPUT final values of object x followed by object y" << endl << endl;
	cout << x;
	cout << y;
	char ch;
	cin >> ch;
	return 0;
}
<commit_msg>Update test.cpp<commit_after>#include <string>
#include <iostream>
using namespace std;

#include "StudentTestScores.h"

int main(){
	int startingNumTestScores=4;
	cout << "CREATE new object x, name = Joe numTestScores = "<< startingNumTestScores << endl << endl;
	StudentTestScores x("Joe", startingNumTestScores);
	cout << "READ standard input for values for test scores of object y, and rename object y" << endl << endl;
	cin >> x;
	cout << "CREATE new object y with name = Chris and default numTestScores" << endl << endl;
	StudentTestScores y("Chris");
	cout << "OUTPUT object y via standard output operators" << endl << endl;
	cout << y;
	cout << "ASSIGN to object y object x using assignment operator" << endl << endl;
	y=x;
	cout << "DISPLAY object x via display function." << endl << endl;
	x.Display();
	cout << "ADD a test score of 79 to object x" << endl << endl;
	x.addTestScore(79);
	cout << "OUTPUT final values of object x followed by object y" << endl << endl;
	cout << x;
	cout << y;
	char ch;
	cin >> ch;
	return 0;
}
<|endoftext|>


<commit_before>/***************************************
** Tsunagari Tile Engine              **
** log.cpp                            **
** Copyright 2011-2013 PariahSoft LLC **
***************************************/

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

#include <iostream>
#include <sstream>

#include "client-conf.h"
#include "log.h"
#include "window.h"
#include "world.h"

#ifdef _WIN32
	#include "os-windows.h"
#endif

#ifdef __APPLE__
	#include "os-mac.h"
#endif

static verbosity_t verb = V_NORMAL;

static time_t startTime;

static std::string& chomp(std::string& str)
{
	std::string::size_type notwhite = str.find_last_not_of(" \t\n\r");
	str.erase(notwhite + 1);
	return str;
}

static std::string ts()
{
	time_t now = GameWindow::time();

	std::ostringstream ts;
	ts.precision(3);
	ts << std::fixed;
	ts << (now - startTime) / (long double)1000.0;
	return "[" + ts.str() + "] ";
}

bool Log::init()
{
	startTime = GameWindow::time();
	return true;
}

void Log::setVerbosity(verbosity_t v)
{
	verb = v;
}

void Log::info(std::string domain, std::string msg)
{
	std::string str = ts() + "Info [" + domain + "] - " + chomp(msg);
	if (verb > V_NORMAL)
		std::cout << str << std::endl;
}

void Log::err(std::string domain, std::string msg)
{
	if (conf.halting == HALT_ERROR) {
		Log::fatal(domain, msg);
		exit(1);
	}
	std::string str = ts() + "Error [" + domain + "] - " + chomp(msg);
	if (verb > V_QUIET) {
		std::cerr << str << std::endl;
		#ifdef _WIN32
			wMessageBox("Tsunagari - Error", str);
		#endif
		#ifdef __APPLE__
			macMessageBox("Tsunagari - Error", str.c_str());
		#endif
	}
}

void Log::fatal(std::string domain, std::string msg)
{
	std::string str = ts() + "Fatal [" + domain + "] - " + chomp(msg);
	std::cerr << str << std::endl;
	#ifdef _WIN32
		wMessageBox("Tsunagari - Fatal", str);
	#endif
	#ifdef __APPLE__
		macMessageBox("Tsunagari - Fatal", str.c_str());
	#endif
}

void Log::reportVerbosityOnStartup()
{
	std::string verbString;
	switch (conf.verbosity)
	{
		case V_QUIET:
			verbString = "QUIET";
			break;
		case V_NORMAL:
			verbString = "NORMAL";
			break;
		case V_VERBOSE:
			verbString = "VERBOSE";
			break;
	}
	std::cout << ts() << "Reporting engine messages in " << verbString
			<< " mode." << std::endl;
}

<commit_msg>log: remove unnecessary header<commit_after>/***************************************
** Tsunagari Tile Engine              **
** log.cpp                            **
** Copyright 2011-2013 PariahSoft LLC **
***************************************/

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

#include <iostream>
#include <sstream>

#include "client-conf.h"
#include "log.h"
#include "window.h"

#ifdef _WIN32
	#include "os-windows.h"
#endif

#ifdef __APPLE__
	#include "os-mac.h"
#endif

static verbosity_t verb = V_NORMAL;

static time_t startTime;

static std::string& chomp(std::string& str)
{
	std::string::size_type notwhite = str.find_last_not_of(" \t\n\r");
	str.erase(notwhite + 1);
	return str;
}

static std::string ts()
{
	time_t now = GameWindow::time();

	std::ostringstream ts;
	ts.precision(3);
	ts << std::fixed;
	ts << (now - startTime) / (long double)1000.0;
	return "[" + ts.str() + "] ";
}

bool Log::init()
{
	startTime = GameWindow::time();
	return true;
}

void Log::setVerbosity(verbosity_t v)
{
	verb = v;
}

void Log::info(std::string domain, std::string msg)
{
	std::string str = ts() + "Info [" + domain + "] - " + chomp(msg);
	if (verb > V_NORMAL)
		std::cout << str << std::endl;
}

void Log::err(std::string domain, std::string msg)
{
	if (conf.halting == HALT_ERROR) {
		Log::fatal(domain, msg);
		exit(1);
	}
	std::string str = ts() + "Error [" + domain + "] - " + chomp(msg);
	if (verb > V_QUIET) {
		std::cerr << str << std::endl;
		#ifdef _WIN32
			wMessageBox("Tsunagari - Error", str);
		#endif
		#ifdef __APPLE__
			macMessageBox("Tsunagari - Error", str.c_str());
		#endif
	}
}

void Log::fatal(std::string domain, std::string msg)
{
	std::string str = ts() + "Fatal [" + domain + "] - " + chomp(msg);
	std::cerr << str << std::endl;
	#ifdef _WIN32
		wMessageBox("Tsunagari - Fatal", str);
	#endif
	#ifdef __APPLE__
		macMessageBox("Tsunagari - Fatal", str.c_str());
	#endif
}

void Log::reportVerbosityOnStartup()
{
	std::string verbString;
	switch (conf.verbosity)
	{
		case V_QUIET:
			verbString = "QUIET";
			break;
		case V_NORMAL:
			verbString = "NORMAL";
			break;
		case V_VERBOSE:
			verbString = "VERBOSE";
			break;
	}
	std::cout << ts() << "Reporting engine messages in " << verbString
			<< " mode." << std::endl;
}

<|endoftext|>


<commit_before>#pragma once

//round a number up to the nearest power of 2
template<typename uint>
inline uint ceil_power2(uint v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	if(sizeof(uint) >= 2) v |= v >> 8;
	if(sizeof(uint) >= 4) v |= v >> 16;
	if(sizeof(uint) >= 8) v |= v >> 32;
	v++;
	return v;
}

inline uint64_t ceil_power2(uint64_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v |= v >> 16;
	v |= v >> 32;
	v++;
	return v;
}
inline uint32_t ceil_power2(uint32_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v |= v >> 16;
	v++;
	return v;
}
inline uint16_t ceil_power2(uint16_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v++;
	return v;
}
inline uint8_t ceil_power2(uint8_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v++;
	return v;
}

//returns true if exactly 1 bit is set
template<typename uint>
inline bool is_power2(uint n){
	return (n && !(n & (n - 1)));
}

template<typename uint>
inline uint clear_bottom_bits(uint n, int num_bits){
	return (n & ~((1 << num_bits)-1));
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros1(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	while((n & 1) == 0){
		++count;
		n >>= 1;
	}
	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros2(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	uint bits = sizeof(uint) * 4;
	do {
		if((n & ((1 << bits) - 1)) == 0){
			count += bits;
			n >>= bits;
		}
		bits >>= 1;
	}while(bits);

	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros3(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	uint bits = sizeof(uint) * 4;
	uint mask = (1 << bits) - 1;
	do {
		if((n & mask) == 0){
			count += bits;
			n >>= bits;
		}
		bits >>= 1;
		mask >>= bits;
	}while(bits && (n & 1) == 0);

	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros4(uint n){
	if(n == 0)
		return 0; //sizeof(uint) * 8;

	uint count = 0;

	if(sizeof(uint) >= 8 && (n & 0xFFFFFFFFULL) == 0){ count += 32; n >>= 32; }
	if(sizeof(uint) >= 4 && (n & 0x0000FFFFULL) == 0){ count += 16; n >>= 16; }
	if(sizeof(uint) >= 2 && (n & 0x000000FFULL) == 0){ count +=  8; n >>=  8; }
	if(sizeof(uint) >= 1 && (n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if(sizeof(uint) >= 1 && (n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if(sizeof(uint) >= 1 && (n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }

	return count;
}

//count how many bits are set
template<typename uint>
inline uint count_bits_set(uint n){
	uint count = 0;
	while(n){
		++count;
		n &= (n - 1);
	}
	return count;
}

<commit_msg>Some specialization to avoid warnings<commit_after>#pragma once

//round a number up to the nearest power of 2
template<typename uint>
inline uint ceil_power2(uint v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	if(sizeof(uint) >= 2) v |= v >> 8;
	if(sizeof(uint) >= 4) v |= v >> 16;
	if(sizeof(uint) >= 8) v |= v >> 32;
	v++;
	return v;
}

inline uint64_t ceil_power2(uint64_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v |= v >> 16;
	v |= v >> 32;
	v++;
	return v;
}
inline uint32_t ceil_power2(uint32_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v |= v >> 16;
	v++;
	return v;
}
inline uint16_t ceil_power2(uint16_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v |= v >> 8;
	v++;
	return v;
}
inline uint8_t ceil_power2(uint8_t v) {
	v--;
	v |= v >> 1;
	v |= v >> 2;
	v |= v >> 4;
	v++;
	return v;
}

//returns true if exactly 1 bit is set
template<typename uint>
inline bool is_power2(uint n){
	return (n && !(n & (n - 1)));
}

template<typename uint>
inline uint clear_bottom_bits(uint n, int num_bits){
	return (n & ~((1 << num_bits)-1));
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros1(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	while((n & 1) == 0){
		++count;
		n >>= 1;
	}
	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros2(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	uint bits = sizeof(uint) * 4;
	do {
		if((n & ((1 << bits) - 1)) == 0){
			count += bits;
			n >>= bits;
		}
		bits >>= 1;
	}while(bits);

	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros3(uint n){
	if(n == 0)
		return 0;//sizeof(uint) * 8;

	uint count = 0;
	uint bits = sizeof(uint) * 4;
	uint mask = (1 << bits) - 1;
	do {
		if((n & mask) == 0){
			count += bits;
			n >>= bits;
		}
		bits >>= 1;
		mask >>= bits;
	}while(bits && (n & 1) == 0);

	return count;
}

//count the trailing zeroes, essentially what power of 2 is it
template<typename uint>
inline uint count_bottom_zeros4(uint n){
	if(n == 0)
		return 0; //sizeof(uint) * 8;

	uint count = 0;

	if(sizeof(uint) >= 8 && (n & 0xFFFFFFFFULL) == 0){ count += 32; n >>= 32; }
	if(sizeof(uint) >= 4 && (n & 0x0000FFFFULL) == 0){ count += 16; n >>= 16; }
	if(sizeof(uint) >= 2 && (n & 0x000000FFULL) == 0){ count +=  8; n >>=  8; }
	if(sizeof(uint) >= 1 && (n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if(sizeof(uint) >= 1 && (n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if(sizeof(uint) >= 1 && (n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }

	return count;
}
inline uint8_t count_bottom_zeros4(uint8_t n){
	if(n == 0)
		return 0;
	uint8_t count = 0;
	if((n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if((n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if((n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }
	return count;
}
inline uint16_t count_bottom_zeros4(uint16_t n){
	if(n == 0)
		return 0;
	uint16_t count = 0;
	if((n & 0x000000FFULL) == 0){ count +=  8; n >>=  8; }
	if((n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if((n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if((n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }
	return count;
}
inline uint32_t count_bottom_zeros4(uint32_t n){
	if(n == 0)
		return 0;
	uint32_t count = 0;
	if((n & 0x0000FFFFULL) == 0){ count += 16; n >>= 16; }
	if((n & 0x000000FFULL) == 0){ count +=  8; n >>=  8; }
	if((n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if((n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if((n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }
	return count;
}
inline uint64_t count_bottom_zeros4(uint64_t n){
	if(n == 0)
		return 0;
	uint64_t count = 0;
	if((n & 0xFFFFFFFFULL) == 0){ count += 32; n >>= 32; }
	if((n & 0x0000FFFFULL) == 0){ count += 16; n >>= 16; }
	if((n & 0x000000FFULL) == 0){ count +=  8; n >>=  8; }
	if((n & 0x0000000FULL) == 0){ count +=  4; n >>=  4; }
	if((n & 0x00000003ULL) == 0){ count +=  2; n >>=  2; }
	if((n & 0x00000001ULL) == 0){ count +=  1; n >>=  1; }
	return count;
}

//count how many bits are set
template<typename uint>
inline uint count_bits_set(uint n){
	uint count = 0;
	while(n){
		++count;
		n &= (n - 1);
	}
	return count;
}

<|endoftext|>


<commit_before>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2014 Mohammed Sameer <msameer@foolab.org>
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "platformsettings.h"
#include <QDir>
#include <QSettings>
#include <Quill>
#if defined(QT4)
#include <QDeclarativeInfo>
#elif defined(QT5)
#include <QQmlInfo>
#endif
#include "quillitem.h"

#ifdef SAILFISH
#define PATH "/usr/share/cameraplus/config/cameraplus.ini"
#else
#define PATH "/usr/share/harbour-cameraplus/share/cameraplus/config/cameraplus.ini"
#endif

#define PREVIEW_SIZE                             QSize(854, 480)
#define PREVIEW_FLAVOR_NAME                      QString("screen")
#define GRID_SIZE                                QSize(170, 170)
#define GRID_FLAVOR_NAME                         QString("cropped")
#define TEMPORARY_FILE_PATH                      "%1%2.config%2quill%2tmp"
#define THUMBNAIL_EXTENSION                      QString("jpeg")
#define THUMBNAIL_CREATION_ENABLED               true
#define DBUS_THUMBNAILING_ENABLED                true
#define BACKGROUND_RENDERING_COLOR               QColor(Qt::black)
#define MAX_TEXTURE_SIZE                         QSize(2048, 2048)

#ifdef HARMATTAN
#define IMAGE_PATH QString("%1%2MyDocs%2DCIM%2").arg(QDir::homePath()).arg(QDir::separator())
#define VIDEO_PATH IMAGE_PATH
#define TEMP_VIDEO QString("%1%2MyDocs%2.cameraplus%2").arg(QDir::homePath()).arg(QDir::separator())
#endif

#ifdef SAILFISH
#define IMAGE_PATH QString("%1%2Pictures%2Camera%2").arg(QDir::homePath()).arg(QDir::separator())
#define VIDEO_PATH QString("%1%2Videos%2Camera%2").arg(QDir::homePath()).arg(QDir::separator())
#define TEMP_VIDEO VIDEO_PATH
#endif

PlatformSettings::PlatformSettings(QObject *parent) :
  QObject(parent), m_settings(new QSettings(PATH, QSettings::IniFormat)) {

}

PlatformSettings::~PlatformSettings() {
  delete m_settings;
}

QSize PlatformSettings::previewSize() {
  return m_settings->value("quill/previewSize", PREVIEW_SIZE).toSize();
}

QString PlatformSettings::previewFlavorName() {
  return m_settings->value("quill/previewFlavorName", PREVIEW_FLAVOR_NAME).toString();
}

QSize PlatformSettings::gridSize() {
  return m_settings->value("quill/gridSize", GRID_SIZE).toSize();
}

QString PlatformSettings::gridFlavorName() {
  return m_settings->value("quill/gridFlavorName", GRID_FLAVOR_NAME).toString();
}

QString PlatformSettings::thumbnailExtension() {
  return m_settings->value("quill/thumbnailExtension", THUMBNAIL_EXTENSION).toString();
}

QColor PlatformSettings::backgroundRenderingColor() {
  return m_settings->value("quill/backgroundRenderingColor",
			   BACKGROUND_RENDERING_COLOR).value<QColor>();
}

bool PlatformSettings::isDBusThumbnailingEnabled() {
  return m_settings->value("quill/dbusThumbnailingEnabled", DBUS_THUMBNAILING_ENABLED).toBool();
}

bool PlatformSettings::isThumbnailCreationEnabled() {
  return m_settings->value("quill/thumbnailCreationEnabled", THUMBNAIL_CREATION_ENABLED).toBool();
}

QString PlatformSettings::temporaryFilePath() {
  QString defaultPath = QString(TEMPORARY_FILE_PATH).arg(QDir::homePath()).arg(QDir::separator());
  return m_settings->value("quill/temporaryFilePath", defaultPath).toString();
}

void PlatformSettings::init() {
  Quill::setPreviewLevelCount(3);

  {
    // cropped display level
    QSize size = gridSize();
    int len = qMax(size.width(), size.height());
    Quill::setThumbnailFlavorName(QuillItem::DisplayLevelCropped, gridFlavorName());
    Quill::setPreviewSize(QuillItem::DisplayLevelCropped, QSize(len, len));
    Quill::setMinimumPreviewSize(QuillItem::DisplayLevelCropped, QSize(len, len));
  }

  {
    // full screen display level
    QSize size = previewSize();
    int len = qMax(size.width(), size.height());

    Quill::setThumbnailFlavorName(QuillItem::DisplayLevelFullScreen, previewFlavorName());
    Quill::setPreviewSize(QuillItem::DisplayLevelFullScreen, QSize(len, len));
  }

  // large display level
  Quill::setPreviewSize(QuillItem::DisplayLevelLarge, MAX_TEXTURE_SIZE);

  Quill::setThumbnailExtension(thumbnailExtension());
  Quill::setBackgroundRenderingColor(backgroundRenderingColor());
  Quill::setDBusThumbnailingEnabled(isDBusThumbnailingEnabled());
  Quill::setThumbnailCreationEnabled(isThumbnailCreationEnabled());

  QString tempPath = temporaryFilePath();
  QDir().mkpath(tempPath);
  Quill::setTemporaryFilePath(tempPath);
}

PlatformSettings::Service PlatformSettings::service(const QString& id) {
  PlatformSettings::Service service;
  m_settings->beginGroup(id);

  service.m_enabled = m_settings->value("enabled", false).toBool();
  service.m_type = m_settings->value("type").toString();
  service.m_path = m_settings->value("path").toString();
  service.m_interface = m_settings->value("interface").toString();
  service.m_dest = m_settings->value("dest").toString();
  service.m_method = m_settings->value("method").toString();

  m_settings->endGroup();

  return service;
}

QString PlatformSettings::imageCaptureStartedSound() const {
  return m_settings->value("sounds/imageCaptureStarted").toString();
}

QString PlatformSettings::imageCaptureEndedSound() const {
  return m_settings->value("sounds/imageCaptureEnded").toString();
}

QString PlatformSettings::videoRecordingStartedSound() const {
  return m_settings->value("sounds/videoRecordingStarted").toString();
}

QString PlatformSettings::videoRecordingEndedSound() const {
  return m_settings->value("sounds/videoRecordingEnded").toString();
}

QString PlatformSettings::autoFocusAcquiredSound() const {
  return m_settings->value("sounds/autoFocusAcquired").toString();
}

QString PlatformSettings::autoFocusFailedSound() const {
  return m_settings->value("sounds/autoFocusFailed").toString();
}

QString PlatformSettings::imagePath() {
  if (m_image.isEmpty()) {
    m_image = canonicalPath(IMAGE_PATH);
  }

  return m_image;
}

QString PlatformSettings::videoPath() {
  if (m_video.isEmpty()) {
    m_video = canonicalPath(VIDEO_PATH);
  }

  return m_video;
}

QString PlatformSettings::temporaryVideoPath() {
  if (m_temp.isEmpty()) {
    m_temp = canonicalPath(TEMP_VIDEO);
  }

  return m_temp;
}

QString PlatformSettings::canonicalPath(const QString& path) const {
  if (!QDir::root().mkpath(path)) {
    qmlInfo(this) << "Failed to create path" << path;
    return QString();
  }

  QString newPath = QFileInfo(path).canonicalFilePath();

  if (newPath.isEmpty()) {
    return newPath;
  }

  if (!newPath.endsWith(QDir::separator())) {
    newPath.append(QDir::separator());
  }

  return newPath;
}
<commit_msg>Fix cameraplus.ini path. The condition was reversed<commit_after>/*!
 * This file is part of CameraPlus.
 *
 * Copyright (C) 2012-2014 Mohammed Sameer <msameer@foolab.org>
 *
 * 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 Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "platformsettings.h"
#include <QDir>
#include <QSettings>
#include <Quill>
#if defined(QT4)
#include <QDeclarativeInfo>
#elif defined(QT5)
#include <QQmlInfo>
#endif
#include "quillitem.h"

#ifdef HARMATTAN
#define PATH "/usr/share/cameraplus/config/cameraplus.ini"
#else
#define PATH "/usr/share/harbour-cameraplus/share/cameraplus/config/cameraplus.ini"
#endif

#define PREVIEW_SIZE                             QSize(854, 480)
#define PREVIEW_FLAVOR_NAME                      QString("screen")
#define GRID_SIZE                                QSize(170, 170)
#define GRID_FLAVOR_NAME                         QString("cropped")
#define TEMPORARY_FILE_PATH                      "%1%2.config%2quill%2tmp"
#define THUMBNAIL_EXTENSION                      QString("jpeg")
#define THUMBNAIL_CREATION_ENABLED               true
#define DBUS_THUMBNAILING_ENABLED                true
#define BACKGROUND_RENDERING_COLOR               QColor(Qt::black)
#define MAX_TEXTURE_SIZE                         QSize(2048, 2048)

#ifdef HARMATTAN
#define IMAGE_PATH QString("%1%2MyDocs%2DCIM%2").arg(QDir::homePath()).arg(QDir::separator())
#define VIDEO_PATH IMAGE_PATH
#define TEMP_VIDEO QString("%1%2MyDocs%2.cameraplus%2").arg(QDir::homePath()).arg(QDir::separator())
#endif

#ifdef SAILFISH
#define IMAGE_PATH QString("%1%2Pictures%2Camera%2").arg(QDir::homePath()).arg(QDir::separator())
#define VIDEO_PATH QString("%1%2Videos%2Camera%2").arg(QDir::homePath()).arg(QDir::separator())
#define TEMP_VIDEO VIDEO_PATH
#endif

PlatformSettings::PlatformSettings(QObject *parent) :
  QObject(parent), m_settings(new QSettings(PATH, QSettings::IniFormat)) {

}

PlatformSettings::~PlatformSettings() {
  delete m_settings;
}

QSize PlatformSettings::previewSize() {
  return m_settings->value("quill/previewSize", PREVIEW_SIZE).toSize();
}

QString PlatformSettings::previewFlavorName() {
  return m_settings->value("quill/previewFlavorName", PREVIEW_FLAVOR_NAME).toString();
}

QSize PlatformSettings::gridSize() {
  return m_settings->value("quill/gridSize", GRID_SIZE).toSize();
}

QString PlatformSettings::gridFlavorName() {
  return m_settings->value("quill/gridFlavorName", GRID_FLAVOR_NAME).toString();
}

QString PlatformSettings::thumbnailExtension() {
  return m_settings->value("quill/thumbnailExtension", THUMBNAIL_EXTENSION).toString();
}

QColor PlatformSettings::backgroundRenderingColor() {
  return m_settings->value("quill/backgroundRenderingColor",
			   BACKGROUND_RENDERING_COLOR).value<QColor>();
}

bool PlatformSettings::isDBusThumbnailingEnabled() {
  return m_settings->value("quill/dbusThumbnailingEnabled", DBUS_THUMBNAILING_ENABLED).toBool();
}

bool PlatformSettings::isThumbnailCreationEnabled() {
  return m_settings->value("quill/thumbnailCreationEnabled", THUMBNAIL_CREATION_ENABLED).toBool();
}

QString PlatformSettings::temporaryFilePath() {
  QString defaultPath = QString(TEMPORARY_FILE_PATH).arg(QDir::homePath()).arg(QDir::separator());
  return m_settings->value("quill/temporaryFilePath", defaultPath).toString();
}

void PlatformSettings::init() {
  Quill::setPreviewLevelCount(3);

  {
    // cropped display level
    QSize size = gridSize();
    int len = qMax(size.width(), size.height());
    Quill::setThumbnailFlavorName(QuillItem::DisplayLevelCropped, gridFlavorName());
    Quill::setPreviewSize(QuillItem::DisplayLevelCropped, QSize(len, len));
    Quill::setMinimumPreviewSize(QuillItem::DisplayLevelCropped, QSize(len, len));
  }

  {
    // full screen display level
    QSize size = previewSize();
    int len = qMax(size.width(), size.height());

    Quill::setThumbnailFlavorName(QuillItem::DisplayLevelFullScreen, previewFlavorName());
    Quill::setPreviewSize(QuillItem::DisplayLevelFullScreen, QSize(len, len));
  }

  // large display level
  Quill::setPreviewSize(QuillItem::DisplayLevelLarge, MAX_TEXTURE_SIZE);

  Quill::setThumbnailExtension(thumbnailExtension());
  Quill::setBackgroundRenderingColor(backgroundRenderingColor());
  Quill::setDBusThumbnailingEnabled(isDBusThumbnailingEnabled());
  Quill::setThumbnailCreationEnabled(isThumbnailCreationEnabled());

  QString tempPath = temporaryFilePath();
  QDir().mkpath(tempPath);
  Quill::setTemporaryFilePath(tempPath);
}

PlatformSettings::Service PlatformSettings::service(const QString& id) {
  PlatformSettings::Service service;
  m_settings->beginGroup(id);

  service.m_enabled = m_settings->value("enabled", false).toBool();
  service.m_type = m_settings->value("type").toString();
  service.m_path = m_settings->value("path").toString();
  service.m_interface = m_settings->value("interface").toString();
  service.m_dest = m_settings->value("dest").toString();
  service.m_method = m_settings->value("method").toString();

  m_settings->endGroup();

  return service;
}

QString PlatformSettings::imageCaptureStartedSound() const {
  return m_settings->value("sounds/imageCaptureStarted").toString();
}

QString PlatformSettings::imageCaptureEndedSound() const {
  return m_settings->value("sounds/imageCaptureEnded").toString();
}

QString PlatformSettings::videoRecordingStartedSound() const {
  return m_settings->value("sounds/videoRecordingStarted").toString();
}

QString PlatformSettings::videoRecordingEndedSound() const {
  return m_settings->value("sounds/videoRecordingEnded").toString();
}

QString PlatformSettings::autoFocusAcquiredSound() const {
  return m_settings->value("sounds/autoFocusAcquired").toString();
}

QString PlatformSettings::autoFocusFailedSound() const {
  return m_settings->value("sounds/autoFocusFailed").toString();
}

QString PlatformSettings::imagePath() {
  if (m_image.isEmpty()) {
    m_image = canonicalPath(IMAGE_PATH);
  }

  return m_image;
}

QString PlatformSettings::videoPath() {
  if (m_video.isEmpty()) {
    m_video = canonicalPath(VIDEO_PATH);
  }

  return m_video;
}

QString PlatformSettings::temporaryVideoPath() {
  if (m_temp.isEmpty()) {
    m_temp = canonicalPath(TEMP_VIDEO);
  }

  return m_temp;
}

QString PlatformSettings::canonicalPath(const QString& path) const {
  if (!QDir::root().mkpath(path)) {
    qmlInfo(this) << "Failed to create path" << path;
    return QString();
  }

  QString newPath = QFileInfo(path).canonicalFilePath();

  if (newPath.isEmpty()) {
    return newPath;
  }

  if (!newPath.endsWith(QDir::separator())) {
    newPath.append(QDir::separator());
  }

  return newPath;
}
<|endoftext|>


<commit_before>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Scott Zuk
//         szuk AT telusplanet DOT net
//////////////////////////////////////////////////////////////////////////////

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <sipxunit/TestUtilities.h>

#include <os/OsDefs.h>
#include <os/OsTimerTask.h>
#include <os/OsProcess.h>
#include <os/OsNatAgentTask.h>
#include <net/SipMessage.h>
#include <net/SipUserAgent.h>
#include <net/SipLineMgr.h>
#include <net/SipRefreshMgr.h>

#define SHUTDOWN_TEST_ITERATIONS 3

/**
 * Unittest for SipUserAgent
 */
class SipUserAgentTest : public CppUnit::TestCase
{
      CPPUNIT_TEST_SUITE(SipUserAgentTest);
      CPPUNIT_TEST(testShutdownBlocking);
      CPPUNIT_TEST(testShutdownNonBlocking);
      CPPUNIT_TEST_SUITE_END();

public:

   // OsProcess doesn't provide any thread info so this method returns
   // the number of threads running under the process given by PID.
   // FIXME: Only implemented for linux, always returns 1 otherwise.
   int getNumThreads( int PID )
   {
       int numThreads = 1;

#ifdef __linux__
       // /proc parsing stolen from OsProcessIteratorLinux.cpp
       OsStatus retval = OS_FAILED;
       char pidString[20];
       snprintf(pidString, 20, "%d", PID);

       OsPath fullProcName = "/proc/";
       fullProcName += pidString;
       fullProcName += "/status";
       OsFileLinux procFile(fullProcName);
       if (procFile.open(OsFile::READ_ONLY) == OS_SUCCESS)
       {
           long len = 5000; //since the length is always 0 for these files, lets try to read 5k
           char *buffer = new char[len+1];
           if (buffer)
           {
               unsigned long bytesRead;
               procFile.read((void *)buffer,(unsigned long)len,bytesRead);

               if (bytesRead)
               {
                   procFile.close();
                   //null-terminate the string
                   buffer[bytesRead] = 0;
                   //now parse the info we need
                   char *ptr = strtok(buffer,"\n");
                   while(ptr)
                   {
                       if (memcmp(ptr,"Threads:",8) == 0)
                       {
                           numThreads = atoi(ptr+8);
                       }

                       ptr = strtok(NULL,"\n");
                   }

                   //say we are successful
                   retval = OS_SUCCESS;
               }
               else
                   osPrintf("Couldn't read bytes in readProcFile\n");

               delete [] buffer;
           }

           procFile.close();
       }
#endif
       return numThreads;
   }

   void testShutdownBlocking()
   {
      int myPID = OsProcess::getCurrentPID();
      int startingThreads = getNumThreads(myPID);

      // Simple invite message from siptest/src/siptest/invite.txt
      const char* SimpleMessage =
          "INVITE sip:1@192.168.0.6 SIP/2.0\r\n"
          "Route: <sip:foo@192.168.0.4:5064;lr>\r\n"
          "From: <sip:888@10.1.1.144;user=phone>;tag=bbb\r\n"
          "To: <sip:3000@192.168.0.3:3000;user=phone>\r\n"
          "Call-Id: 8\r\n"
          "Cseq: 1 INVITE\r\n"
          "Content-Length: 0\r\n"
          "\r\n";

      SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) );

      for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i)
      {
         // Limit life time of lineMgr and refreshMgr. They should be freed
         // before releasing OsNatAgentTask instance, or we will crash.
         {
            SipLineMgr    lineMgr;
            SipRefreshMgr refreshMgr;

            lineMgr.StartLineMgr();
            lineMgr.initializeRefreshMgr( &refreshMgr );

            SipUserAgent sipUA( 5090
                              ,5090
                              ,5091
                              ,NULL     // default publicAddress
                              ,NULL     // default defaultUser
                              ,"127.0.0.1"     // default defaultSipAddress
                              ,NULL     // default sipProxyServers
                              ,NULL     // default sipDirectoryServers
                              ,NULL     // default sipRegistryServers
                              ,NULL     // default authenticationScheme
                              ,NULL     // default authenicateRealm
                              ,NULL     // default authenticateDb
                              ,NULL     // default authorizeUserIds
                              ,NULL     // default authorizePasswords
                              ,&lineMgr
                              );

            sipUA.start();
            refreshMgr.init(&sipUA);

            sipUA.send(testMsg);

            // Wait long enough for some stack timeouts/retansmits to occur
            OsTask::delay(10000); // 10 seconds

            // Shut down the tasks in reverse order.
            refreshMgr.requestShutdown();
            sipUA.shutdown(TRUE);
            lineMgr.requestShutdown();

            CPPUNIT_ASSERT(sipUA.isShutdownDone());
         }

         OsTimerTask::destroyTimerTask();
         OsNatAgentTask::releaseInstance();

         // Test to see that all the threads created by the above operations
         // get properly shut down.
         // Since the threads do not shut down synchronously with the above
         // calls, we have to wait before we know they will be cleared.
         OsTask::delay(1000);   // 1 second
         int numThreads = getNumThreads(myPID);
         KNOWN_BUG("threads not shutting down", "XSL-152");
         CPPUNIT_ASSERT_EQUAL(startingThreads,numThreads);
      }
   };

   void testShutdownNonBlocking()
   {
      int myPID = OsProcess::getCurrentPID();
      int startingThreads = getNumThreads(myPID);

      // Simple invite message from siptest/src/siptest/invite.txt
      const char* SimpleMessage =
          "INVITE sip:1@192.168.0.6 SIP/2.0\r\n"
          "Route: <sip:foo@192.168.0.4:5064;lr>\r\n"
          "From: <sip:888@10.1.1.144;user=phone>;tag=bbb\r\n"
          "To: <sip:3000@192.168.0.3:3000;user=phone>\r\n"
          "Call-Id: 8\r\n"
          "Cseq: 1 INVITE\r\n"
          "Content-Length: 0\r\n"
          "\r\n";

      SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) );

      for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i)
      {
         // Limit life time of lineMgr and refreshMgr. They should be freed
         // before releasing OsNatAgentTask instance, or we will crash.
         {
            SipLineMgr    lineMgr;
            SipRefreshMgr refreshMgr;

            lineMgr.StartLineMgr();
            lineMgr.initializeRefreshMgr( &refreshMgr );

            SipUserAgent sipUA( 5090
                              ,5090
                              ,5091
                              ,NULL     // default publicAddress
                              ,NULL     // default defaultUser
                              ,"127.0.0.1"     // default defaultSipAddress
                              ,NULL     // default sipProxyServers
                              ,NULL     // default sipDirectoryServers
                              ,NULL     // default sipRegistryServers
                              ,NULL     // default authenticationScheme
                              ,NULL     // default authenicateRealm
                              ,NULL     // default authenticateDb
                              ,NULL     // default authorizeUserIds
                              ,NULL     // default authorizePasswords
                              ,&lineMgr
                              );

            sipUA.start();
            refreshMgr.init(&sipUA);

            sipUA.send(testMsg);

            // Wait long enough for some stack timeouts/retransmits to occur
            OsTask::delay(10000); // 10 seconds

            sipUA.shutdown(FALSE);
            lineMgr.requestShutdown();
            refreshMgr.requestShutdown();

            while(!sipUA.isShutdownDone())
            {
               ;
            }
            CPPUNIT_ASSERT(sipUA.isShutdownDone());
         }

         OsTimerTask::destroyTimerTask();
         OsNatAgentTask::releaseInstance();

         // Test to see that all the threads created by the above operations
         // get properly shut down.
         // Since the threads do not shut down synchronously with the above
         // calls, we have to wait before we know they will be cleared.
         OsTask::delay(1000);   // 1 second
         int numThreads = getNumThreads(myPID);
         CPPUNIT_ASSERT_EQUAL(startingThreads,numThreads);
      }
   };

};

CPPUNIT_TEST_SUITE_REGISTRATION(SipUserAgentTest);
<commit_msg>[XSL-152] Fix sipXtackLib unittests under Linux.<commit_after>//
// Copyright (C) 2004-2006 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2004-2006 Pingtel Corp.  All rights reserved.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
///////////////////////////////////////////////////////////////////////////////

// Author: Scott Zuk
//         szuk AT telusplanet DOT net
//////////////////////////////////////////////////////////////////////////////

#include <cppunit/extensions/HelperMacros.h>
#include <cppunit/TestCase.h>
#include <sipxunit/TestUtilities.h>

#include <os/OsDefs.h>
#include <os/OsTimerTask.h>
#include <os/OsProcess.h>
#include <os/OsNatAgentTask.h>
#include <net/SipMessage.h>
#include <net/SipUserAgent.h>
#include <net/SipLineMgr.h>
#include <net/SipRefreshMgr.h>

#define SHUTDOWN_TEST_ITERATIONS 3

/**
 * Unittest for SipUserAgent
 */
class SipUserAgentTest : public CppUnit::TestCase
{
      CPPUNIT_TEST_SUITE(SipUserAgentTest);
      CPPUNIT_TEST(testShutdownBlocking);
      CPPUNIT_TEST(testShutdownNonBlocking);
      CPPUNIT_TEST_SUITE_END();

public:

   // OsProcess doesn't provide any thread info so this method returns
   // the number of threads running under the process given by PID.
   // FIXME: Only implemented for linux, always returns 1 otherwise.
   int getNumThreads( int PID )
   {
       int numThreads = 1;

#ifdef __linux__
       // /proc parsing stolen from OsProcessIteratorLinux.cpp
       OsStatus retval = OS_FAILED;
       char pidString[20];
       snprintf(pidString, 20, "%d", PID);

       OsPath fullProcName = "/proc/";
       fullProcName += pidString;
       fullProcName += "/status";
       OsFileLinux procFile(fullProcName);
       if (procFile.open(OsFile::READ_ONLY) == OS_SUCCESS)
       {
           long len = 5000; //since the length is always 0 for these files, lets try to read 5k
           char *buffer = new char[len+1];
           if (buffer)
           {
               unsigned long bytesRead;
               procFile.read((void *)buffer,(unsigned long)len,bytesRead);

               if (bytesRead)
               {
                   procFile.close();
                   //null-terminate the string
                   buffer[bytesRead] = 0;
                   //now parse the info we need
                   char *ptr = strtok(buffer,"\n");
                   while(ptr)
                   {
                       if (memcmp(ptr,"Threads:",8) == 0)
                       {
                           numThreads = atoi(ptr+8);
                       }

                       ptr = strtok(NULL,"\n");
                   }

                   //say we are successful
                   retval = OS_SUCCESS;
               }
               else
                   osPrintf("Couldn't read bytes in readProcFile\n");

               delete [] buffer;
           }

           procFile.close();
       }
#endif
       return numThreads;
   }

   void testShutdownBlocking()
   {
      int myPID = OsProcess::getCurrentPID();
      int startingThreads;

      // Stop TimerTask and NatAgentTask before counting threads.
      // Some tests do not bother stopping them, so they may come started.
      OsTimerTask::destroyTimerTask();
      OsNatAgentTask::releaseInstance();

      // Count number of threads now.
      startingThreads = getNumThreads(myPID);

      // Simple invite message from siptest/src/siptest/invite.txt
      const char* SimpleMessage =
          "INVITE sip:1@192.168.0.6 SIP/2.0\r\n"
          "Route: <sip:foo@192.168.0.4:5064;lr>\r\n"
          "From: <sip:888@10.1.1.144;user=phone>;tag=bbb\r\n"
          "To: <sip:3000@192.168.0.3:3000;user=phone>\r\n"
          "Call-Id: 8\r\n"
          "Cseq: 1 INVITE\r\n"
          "Content-Length: 0\r\n"
          "\r\n";

      SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) );

      for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i)
      {
         // Limit life time of lineMgr and refreshMgr. They should be freed
         // before releasing OsNatAgentTask instance, or we will crash.
         {
            SipLineMgr    lineMgr;
            SipRefreshMgr refreshMgr;

            lineMgr.StartLineMgr();
            lineMgr.initializeRefreshMgr( &refreshMgr );

            SipUserAgent sipUA( 5090
                              ,5090
                              ,5091
                              ,NULL     // default publicAddress
                              ,NULL     // default defaultUser
                              ,"127.0.0.1"     // default defaultSipAddress
                              ,NULL     // default sipProxyServers
                              ,NULL     // default sipDirectoryServers
                              ,NULL     // default sipRegistryServers
                              ,NULL     // default authenticationScheme
                              ,NULL     // default authenicateRealm
                              ,NULL     // default authenticateDb
                              ,NULL     // default authorizeUserIds
                              ,NULL     // default authorizePasswords
                              ,&lineMgr
                              );

            sipUA.start();
            refreshMgr.init(&sipUA);

            sipUA.send(testMsg);

            // Wait long enough for some stack timeouts/retansmits to occur
            OsTask::delay(10000); // 10 seconds

            // Shut down the tasks in reverse order.
            refreshMgr.requestShutdown();
            sipUA.shutdown(TRUE);
            lineMgr.requestShutdown();

            CPPUNIT_ASSERT(sipUA.isShutdownDone());
         }

         // Stop TimerTask and NatAgentTask again before counting threads.
         // They were started while testing.
         OsTimerTask::destroyTimerTask();
         OsNatAgentTask::releaseInstance();

         // Test to see that all the threads created by the above operations
         // get properly shut down.
         // Since the threads do not shut down synchronously with the above
         // calls, we have to wait before we know they will be cleared.
         OsTask::delay(1000);   // 1 second
         int numThreads = getNumThreads(myPID);
         CPPUNIT_ASSERT_EQUAL(startingThreads,numThreads);
      }
   };

   void testShutdownNonBlocking()
   {
      int myPID = OsProcess::getCurrentPID();
      int startingThreads;

      // Stop TimerTask and NatAgentTask before counting threads.
      // Some tests do not bother stopping them, so they may come started.
      OsTimerTask::destroyTimerTask();
      OsNatAgentTask::releaseInstance();

      // Count number of threads now.
      startingThreads = getNumThreads(myPID);

      // Simple invite message from siptest/src/siptest/invite.txt
      const char* SimpleMessage =
          "INVITE sip:1@192.168.0.6 SIP/2.0\r\n"
          "Route: <sip:foo@192.168.0.4:5064;lr>\r\n"
          "From: <sip:888@10.1.1.144;user=phone>;tag=bbb\r\n"
          "To: <sip:3000@192.168.0.3:3000;user=phone>\r\n"
          "Call-Id: 8\r\n"
          "Cseq: 1 INVITE\r\n"
          "Content-Length: 0\r\n"
          "\r\n";

      SipMessage testMsg( SimpleMessage, strlen( SimpleMessage ) );

      for(int i = 0; i < SHUTDOWN_TEST_ITERATIONS; ++i)
      {
         // Limit life time of lineMgr and refreshMgr. They should be freed
         // before releasing OsNatAgentTask instance, or we will crash.
         {
            SipLineMgr    lineMgr;
            SipRefreshMgr refreshMgr;

            lineMgr.StartLineMgr();
            lineMgr.initializeRefreshMgr( &refreshMgr );

            SipUserAgent sipUA( 5090
                              ,5090
                              ,5091
                              ,NULL     // default publicAddress
                              ,NULL     // default defaultUser
                              ,"127.0.0.1"     // default defaultSipAddress
                              ,NULL     // default sipProxyServers
                              ,NULL     // default sipDirectoryServers
                              ,NULL     // default sipRegistryServers
                              ,NULL     // default authenticationScheme
                              ,NULL     // default authenicateRealm
                              ,NULL     // default authenticateDb
                              ,NULL     // default authorizeUserIds
                              ,NULL     // default authorizePasswords
                              ,&lineMgr
                              );

            sipUA.start();
            refreshMgr.init(&sipUA);

            sipUA.send(testMsg);

            // Wait long enough for some stack timeouts/retransmits to occur
            OsTask::delay(10000); // 10 seconds

            sipUA.shutdown(FALSE);
            lineMgr.requestShutdown();
            refreshMgr.requestShutdown();

            while(!sipUA.isShutdownDone())
            {
               ;
            }
            CPPUNIT_ASSERT(sipUA.isShutdownDone());
         }

         // Stop TimerTask and NatAgentTask again before counting threads.
         // They were started while testing.
         OsTimerTask::destroyTimerTask();
         OsNatAgentTask::releaseInstance();

         // Test to see that all the threads created by the above operations
         // get properly shut down.
         // Since the threads do not shut down synchronously with the above
         // calls, we have to wait before we know they will be cleared.
         OsTask::delay(1000);   // 1 second
         int numThreads = getNumThreads(myPID);
         CPPUNIT_ASSERT_EQUAL(startingThreads,numThreads);
      }
   };

};

CPPUNIT_TEST_SUITE_REGISTRATION(SipUserAgentTest);
<|endoftext|>


<commit_before>/* <x0/plugins/compress.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2010 Chrisitan Parpart <trapni@gentoo.org>
 */

#include "compress.h"
#include <x0/http/HttpPlugin.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/http/HttpResponse.h>
#include <x0/http/HttpRangeDef.h>
#include <x0/io/CompressFilter.h>
#include <x0/strutils.h>
#include <x0/Types.h>
#include <x0/sysconfig.h>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>

#include <sstream>
#include <iostream>
#include <algorithm>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#if !defined(HAVE_BZLIB_H) && !defined(HAVE_ZLIB_H)
#	warning No compression headers available!
#endif

/**
 * \ingroup plugins
 * \brief serves static files from server's local filesystem to client.
 */
class compress_plugin :
	public x0::HttpPlugin,
	public ICompressPlugin
{
private:
	struct context : public x0::ScopeValue
	{
		std::vector<std::string> content_types_;
		int level_;
		long long min_size_;
		long long max_size_;

		context() :
			content_types_(),				// no types
			level_(9),						// best compression
			min_size_(1024),				// 1 KB
			max_size_(128 * 1024 * 1024)	// 128 MB
		{
		}

		bool contains_mime(const std::string& value) const
		{
			for (auto i = content_types_.begin(), e = content_types_.end(); i != e; ++i)
				if (*i == value)
					return true;

			return false;
		}

		virtual void merge(const x0::ScopeValue *value)
		{
			//if (auto cx = dynamic_cast<const context *>(value))
			{
				; //! \todo
			}
		}
	};

	x0::HttpServer::RequestPostHook::Connection postProcess_;

public:
	compress_plugin(x0::HttpServer& srv, const std::string& name) :
		x0::HttpPlugin(srv, name)
	{
		using namespace std::placeholders;

		postProcess_ = server_.onPostProcess.connect<compress_plugin, &compress_plugin::postProcess>(this);

		declareCVar("CompressTypes", x0::HttpContext::server, &compress_plugin::setup_types);
		declareCVar("CompressLevel", x0::HttpContext::server, &compress_plugin::setup_level);
		declareCVar("CompressMinSize", x0::HttpContext::server, &compress_plugin::setup_minsize);
		declareCVar("CompressMaxSize", x0::HttpContext::server, &compress_plugin::setup_maxsize);
	}

	~compress_plugin() {
		server_.onPostProcess.disconnect(postProcess_);
	}

public: // ICompressPlugin
	virtual void setCompressTypes(const std::vector<std::string>& value)
	{
		server().acquire<context>(this)->content_types_ = value;
	}

	virtual void setCompressLevel(int value)
	{
		server().acquire<context>(this)->level_ = value;
	}

	virtual void setCompressMinSize(int value)
	{
		server().acquire<context>(this)->min_size_ = value;
	}

	virtual void setCompressMaxSize(int value)
	{
		server().acquire<context>(this)->max_size_ = value;
	}

private:
	std::error_code setup_types(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->content_types_);
	}

	std::error_code setup_level(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->level_);
	}

	std::error_code setup_minsize(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->min_size_);
	}

	std::error_code setup_maxsize(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->max_size_);
	}

	void postProcess(x0::HttpRequest *in, x0::HttpResponse *out)
	{
		if (out->headers.contains("Content-Encoding"))
			return; // do not double-encode content

		const context *cx = server_.host(in->hostid()).get<context>(this);
		if (!cx && !(cx = server().get<context>(this)))
			return;

		long long size = 0;
		if (out->headers.contains("Content-Length"))
			size = boost::lexical_cast<int>(out->headers["Content-Length"]);

		if (size < cx->min_size_)
			return;

		if (size > cx->max_size_)
			return;

		if (!cx->contains_mime(out->headers("Content-Type")))
			return;

		if (x0::BufferRef r = in->header("Accept-Encoding"))
		{
			typedef boost::tokenizer<boost::char_separator<char>> tokenizer;

			std::vector<std::string> items(x0::split<std::string>(r.str(), ", "));

#if defined(HAVE_BZLIB_H)
			if (std::find(items.begin(), items.end(), "bzip2") != items.end())
			{
				out->headers.push_back("Content-Encoding", "bzip2");
				out->filter_chain.push_back(std::make_shared<x0::BZip2Filter>(cx->level_));
			}
			else
#endif
#if defined(HAVE_ZLIB_H)
			if (std::find(items.begin(), items.end(), "gzip") != items.end())
			{
				out->headers.push_back("Content-Encoding", "gzip");
				out->filter_chain.push_back(std::make_shared<x0::GZipFilter>(cx->level_));
			}
			else if (std::find(items.begin(), items.end(), "deflate") != items.end())
			{
				out->headers.push_back("Content-Encoding", "deflate");
				out->filter_chain.push_back(std::make_shared<x0::DeflateFilter>(cx->level_));
			}
			else
#endif
				return;

			// response might change according to Accept-Encoding
			if (!out->headers.contains("Vary"))
				out->headers.push_back("Vary", "Accept-Encoding");
			else
				out->headers["Vary"] += ",Accept-Encoding";

			// removing content-length implicitely enables chunked encoding
			out->headers.remove("Content-Length");
		}
	}
};

X0_EXPORT_PLUGIN(compress);
<commit_msg>[plugins] compress: added missing server().release(this)<commit_after>/* <x0/plugins/compress.cpp>
 *
 * This file is part of the x0 web server project and is released under LGPL-3.
 *
 * (c) 2010 Chrisitan Parpart <trapni@gentoo.org>
 */

#include "compress.h"
#include <x0/http/HttpPlugin.h>
#include <x0/http/HttpServer.h>
#include <x0/http/HttpRequest.h>
#include <x0/http/HttpResponse.h>
#include <x0/http/HttpRangeDef.h>
#include <x0/io/CompressFilter.h>
#include <x0/strutils.h>
#include <x0/Types.h>
#include <x0/sysconfig.h>

#include <boost/lexical_cast.hpp>
#include <boost/tokenizer.hpp>

#include <sstream>
#include <iostream>
#include <algorithm>

#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

#if !defined(HAVE_BZLIB_H) && !defined(HAVE_ZLIB_H)
#	warning No compression headers available!
#endif

/**
 * \ingroup plugins
 * \brief serves static files from server's local filesystem to client.
 */
class compress_plugin :
	public x0::HttpPlugin,
	public ICompressPlugin
{
private:
	struct context : public x0::ScopeValue
	{
		std::vector<std::string> content_types_;
		int level_;
		long long min_size_;
		long long max_size_;

		context() :
			content_types_(),				// no types
			level_(9),						// best compression
			min_size_(1024),				// 1 KB
			max_size_(128 * 1024 * 1024)	// 128 MB
		{
		}

		bool contains_mime(const std::string& value) const
		{
			for (auto i = content_types_.begin(), e = content_types_.end(); i != e; ++i)
				if (*i == value)
					return true;

			return false;
		}

		virtual void merge(const x0::ScopeValue *value)
		{
			//if (auto cx = dynamic_cast<const context *>(value))
			{
				; //! \todo
			}
		}
	};

	x0::HttpServer::RequestPostHook::Connection postProcess_;

public:
	compress_plugin(x0::HttpServer& srv, const std::string& name) :
		x0::HttpPlugin(srv, name)
	{
		using namespace std::placeholders;

		postProcess_ = server_.onPostProcess.connect<compress_plugin, &compress_plugin::postProcess>(this);

		declareCVar("CompressTypes", x0::HttpContext::server, &compress_plugin::setup_types);
		declareCVar("CompressLevel", x0::HttpContext::server, &compress_plugin::setup_level);
		declareCVar("CompressMinSize", x0::HttpContext::server, &compress_plugin::setup_minsize);
		declareCVar("CompressMaxSize", x0::HttpContext::server, &compress_plugin::setup_maxsize);
	}

	~compress_plugin() {
		server_.onPostProcess.disconnect(postProcess_);
		server().release(this);
	}

public: // ICompressPlugin
	virtual void setCompressTypes(const std::vector<std::string>& value)
	{
		server().acquire<context>(this)->content_types_ = value;
	}

	virtual void setCompressLevel(int value)
	{
		server().acquire<context>(this)->level_ = value;
	}

	virtual void setCompressMinSize(int value)
	{
		server().acquire<context>(this)->min_size_ = value;
	}

	virtual void setCompressMaxSize(int value)
	{
		server().acquire<context>(this)->max_size_ = value;
	}

private:
	std::error_code setup_types(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->content_types_);
	}

	std::error_code setup_level(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->level_);
	}

	std::error_code setup_minsize(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->min_size_);
	}

	std::error_code setup_maxsize(const x0::SettingsValue& cvar, x0::Scope& s)
	{
		return cvar.load(s.acquire<context>(this)->max_size_);
	}

	void postProcess(x0::HttpRequest *in, x0::HttpResponse *out)
	{
		if (out->headers.contains("Content-Encoding"))
			return; // do not double-encode content

		const context *cx = server_.host(in->hostid()).get<context>(this);
		if (!cx && !(cx = server().get<context>(this)))
			return;

		long long size = 0;
		if (out->headers.contains("Content-Length"))
			size = boost::lexical_cast<int>(out->headers["Content-Length"]);

		if (size < cx->min_size_)
			return;

		if (size > cx->max_size_)
			return;

		if (!cx->contains_mime(out->headers("Content-Type")))
			return;

		if (x0::BufferRef r = in->header("Accept-Encoding"))
		{
			typedef boost::tokenizer<boost::char_separator<char>> tokenizer;

			std::vector<std::string> items(x0::split<std::string>(r.str(), ", "));

#if defined(HAVE_BZLIB_H)
			if (std::find(items.begin(), items.end(), "bzip2") != items.end())
			{
				out->headers.push_back("Content-Encoding", "bzip2");
				out->filter_chain.push_back(std::make_shared<x0::BZip2Filter>(cx->level_));
			}
			else
#endif
#if defined(HAVE_ZLIB_H)
			if (std::find(items.begin(), items.end(), "gzip") != items.end())
			{
				out->headers.push_back("Content-Encoding", "gzip");
				out->filter_chain.push_back(std::make_shared<x0::GZipFilter>(cx->level_));
			}
			else if (std::find(items.begin(), items.end(), "deflate") != items.end())
			{
				out->headers.push_back("Content-Encoding", "deflate");
				out->filter_chain.push_back(std::make_shared<x0::DeflateFilter>(cx->level_));
			}
			else
#endif
				return;

			// response might change according to Accept-Encoding
			if (!out->headers.contains("Vary"))
				out->headers.push_back("Vary", "Accept-Encoding");
			else
				out->headers["Vary"] += ",Accept-Encoding";

			// removing content-length implicitely enables chunked encoding
			out->headers.remove("Content-Length");
		}
	}
};

X0_EXPORT_PLUGIN(compress);
<|endoftext|>


<commit_before>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$
// mapnik
#include <mapnik/point_symbolizer.hpp>

#include <mapnik/image_data.hpp>
#include <mapnik/image_reader.hpp>
// boost
#include <boost/scoped_ptr.hpp>
// stl
#include <iostream>

namespace mapnik
{
    point_symbolizer::point_symbolizer()
        : symbolizer_with_image(boost::shared_ptr<ImageData32>(new ImageData32(4,4))),
          overlap_(false),
          opacity_(1.0)
    {
        //default point symbol is black 4x4px square
        image_->set(0xff000000);
    }

    point_symbolizer::point_symbolizer(std::string const& file,
                                       std::string const& type,
                                       unsigned width,unsigned height)
        : symbolizer_with_image(file, type, width, height),
          overlap_(false),
          opacity_(1.0)
    { }

    point_symbolizer::point_symbolizer(point_symbolizer const& rhs)
        : symbolizer_with_image(rhs),
          overlap_(rhs.overlap_),
          opacity_(rhs.opacity_)
    {}

    void point_symbolizer::set_allow_overlap(bool overlap)
    {
        overlap_ = overlap;
    }

    bool point_symbolizer::get_allow_overlap() const
    {
        return overlap_;
    }
}

<commit_msg>+ corrected init order <commit_after>/*****************************************************************************
 *
 * This file is part of Mapnik (c++ mapping toolkit)
 *
 * Copyright (C) 2006 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
 *
 *****************************************************************************/

//$Id$
// mapnik
#include <mapnik/point_symbolizer.hpp>

#include <mapnik/image_data.hpp>
#include <mapnik/image_reader.hpp>
// boost
#include <boost/scoped_ptr.hpp>
// stl
#include <iostream>

namespace mapnik
{
    point_symbolizer::point_symbolizer()
        : symbolizer_with_image(boost::shared_ptr<ImageData32>(new ImageData32(4,4))),
          opacity_(1.0),
          overlap_(false)

    {
        //default point symbol is black 4x4px square
        image_->set(0xff000000);
    }

    point_symbolizer::point_symbolizer(std::string const& file,
                                       std::string const& type,
                                       unsigned width,unsigned height)
        : symbolizer_with_image(file, type, width, height),
          opacity_(1.0),
          overlap_(false)

    { }

    point_symbolizer::point_symbolizer(point_symbolizer const& rhs)
        : symbolizer_with_image(rhs),
          opacity_(rhs.opacity_),
          overlap_(rhs.overlap_)
    {}

    void point_symbolizer::set_allow_overlap(bool overlap)
    {
        overlap_ = overlap;
    }

    bool point_symbolizer::get_allow_overlap() const
    {
        return overlap_;
    }
}

<|endoftext|>